1 Define functions

## Define function that recodes to numeric, but watches out to coercion to not introduce NAs
colstonumeric <- function(df){
  tryCatch({
    df_num <- as.data.frame(
      lapply(df,
             function(x) { as.numeric(as.character(x))})) 
  },warning = function(stop_on_warning) {
    message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
  }) 
}
##
## Define function that reverse codes items
ReverseCode <- function(df, tonumeric = FALSE, min = NULL, max = NULL) {
  if(tonumeric) df <- colstonumeric(df)
  df <- (max + min) - df
}
##
## Define function that scores only rows with less than 10% NAs (returns NA if all or above threshold percentage of rows are NA); can reverse code if vector of column indexes and min, max are provided.
ScoreLikert <- function(df, napercent = .1, tonumeric = FALSE, reversecols = NULL, min = NULL, max = NULL) {
  reverse_list <- list(reversecols = reversecols, min = min, max = max)
  reverse_check <- !sapply(reverse_list, is.null)
  
  # Recode to numeric, but watch out to coercion to not introduce NAs
  colstonumeric <- function(df){
    tryCatch({
      df_num <- as.data.frame(
        lapply(df,
               function(x) { as.numeric(as.character(x))})) 
    },warning = function(stop_on_warning) {
      message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
    }) 
  }
  
  if(tonumeric) df <- colstonumeric(df)
  
  if(all(reverse_check)){
    df[ ,reversecols] <- (max + min) - df[ ,reversecols]
  }else if(any(reverse_check)){
    stop("Insuficient info for reversing. Please provide: ", paste(names(reverse_list)[!reverse_check], collapse = ", "))
  }
  
  ifelse(rowSums(is.na(df)) > ncol(df) * napercent,
         NA,
         rowSums(df, na.rm = TRUE) * NA ^ (rowSums(!is.na(df)) == 0)
  )
}
##
# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(broom)
# library(emmeans)
# library(rlang)


# Function ANCOVAPost
# Takes Long Data
ANCOVAPost_func <- 
  function(data, id_var, 
           time_var, pre_label, post_label,
           value_var = scores, cond_var, 
           assum_check = TRUE, posthoc = TRUE, 
           p_adjust_method = "bonferroni"){
  
  id_var_enq <- rlang::enquo(id_var)
  id_var_name <- rlang::as_name(id_var_enq)    
  time_var_enq <- rlang::enquo(time_var)
  time_var_name <- rlang::as_name(time_var_enq)
  pre_var_enq <- rlang::enquo(pre_label)
  pre_var_name <- rlang::as_name(pre_var_enq)  
  post_var_enq <- rlang::enquo(post_label)
  post_var_name <- rlang::as_name(post_var_enq)
  cond_var_enq <- rlang::enquo(cond_var)
  cond_var_name <- rlang::as_name(cond_var_enq)
  value_var_enq <- rlang::enquo(value_var)
  value_var_name <- rlang::as_name(value_var_enq) 
  
  data_wider <-
    data %>%
    dplyr::select(!!id_var_enq, !!time_var_enq, !!cond_var_enq, !!value_var_enq) %>%
    spread(key = time_var_name, value = value_var_name) # %>%     # if need to compute change score statistics go from here
    # mutate(difference = !!post_var_enq - !!pre_var_enq)  
    
  # Assumptions
  if(assum_check){
  cat("\n Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group) \n")
  # Create a scatter plot between the covariate (i.e., pretest) and the outcome variable (i.e., posttest)
  scatter_lin <-  
    ggscatter(data_wider, x = pre_var_name, y = post_var_name, color = cond_var_name, 
              add = "reg.line", title = "Linearity assumption") +
      stat_regline_equation(aes(label =  paste(..eq.label.., ..rr.label.., sep = "~~~~"), color = !!cond_var_enq))
  
  cat("\n Homogeneity of regression slopes (interaction term is n.s.) \n")
  data_wider %>% 
    anova_test(as.formula(paste0(post_var_name, " ~ ", cond_var_name, " * ", pre_var_name))) %>% 
    print()   
  
  cat("\n Normality of residuals (Model diagnostics & Shapiro Wilk) \n")
  # Fit the model, the covariate goes first
  model <- 
    lm(as.formula(paste0(post_var_name, " ~ ", cond_var_name, " + ", pre_var_name)),
       data = data_wider)
  cat("\n Inspect the model diagnostic metrics \n")
  model.metrics <- 
    augment(model) %>%
    dplyr::select(-.hat, -.sigma, -.fitted, -.se.fit)  %>%    # Remove details
    print()
  cat("\n Normality of residuals (Shapiro Wilk p>.05) \n")
  shapiro_test(model.metrics$.resid) %>% 
    print()
  
  cat("\n Homogeneity of variances (Levene’s test p>.05) \n")
  model.metrics %>% 
    levene_test(as.formula(paste0(".resid", " ~ ", cond_var_name)) ) %>%     
    print()
  
  cat("\n Outliers (needs to be 0) \n")
  model.metrics %>% 
    filter(abs(.std.resid) > 3) %>%
    as.data.frame() %>% 
    print()
  
  }
  
  cat("\n ANCOVAPost \n")
  res_ancova <- 
    data_wider %>% 
    anova_test(as.formula(paste0(post_var_name, " ~ ",  pre_var_name, " + ", cond_var_name)))       # the covariate needs to be first term 
  get_anova_table(res_ancova) %>% print()
  
  cat("\n Pairwise comparisons \n")
  pwc <- 
    data_wider %>% 
    emmeans_test(as.formula(paste0(post_var_name, " ~ ", cond_var_name)),       
                 covariate = !!pre_var_enq,
                 p.adjust.method = p_adjust_method)
  pwc %>% print()
  cat("\n Display the adjusted means of each group, also called as the estimated marginal means (emmeans) \n")
  get_emmeans(pwc) %>% print()
  
  # Visualization: line plots with p-values
  pwc <- 
    pwc %>% 
    add_xy_position(x = cond_var_name, fun = "mean_se")
  
  line_plot <- 
    ggline(get_emmeans(pwc), x = cond_var_name, y = "emmean") +
      geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2) + 
      stat_pvalue_manual(pwc, hide.ns = TRUE, tip.length = FALSE) +
      labs(subtitle = get_test_label(res_ancova, detailed = TRUE),
           caption = get_pwc_label(pwc))
  
  if(assum_check){
    list(scatter_lin, line_plot)
  }else{
    line_plot
  }
  
}

# ex.
# ANCOVAPost_func(new_anxiety, time_var = time, pre_label = pretest, post_label = posttest,
#           value_var = scores, cond_var = group, assum_check = TRUE, p_adjust_method = "bonferroni")
# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(rlang)

# Define Function for Mixed Anova
tw_mixedANOVA_func <- 
  function(data, id_var, cond_var, time_var, value_var, 
           assum_check = TRUE, posthoc_sig_interac = FALSE, posthoc_ns_interac = FALSE,
           p_adjust_method = "bonferroni"){
    
    # input dataframe needs to have columns names diffrent from "variable" and "value" because it collides with rstatix::shapiro_test
    
    id_var_enq <- rlang::enquo(id_var)  
    cond_var_enq <- rlang::enquo(cond_var)
    cond_var_name <- rlang::as_name(cond_var_enq)
    time_var_enq <- rlang::enquo(time_var)
    time_var_name <- rlang::as_name(time_var_enq)
    value_var_enq <- rlang::enquo(value_var)
    value_var_name <- rlang::as_name(value_var_enq)
    
    data <-                  # need to subset becuase of strange contrasts error in anova_test()
      data %>%
      dplyr::select(!!id_var_enq, !!time_var_enq, !!cond_var_enq, !!value_var_enq) 
    
    # Assumptions
    if(assum_check){
      cat("\n Outliers \n")
      data %>%
        dplyr::group_by(!!time_var_enq, !!cond_var_enq) %>%
        rstatix::identify_outliers(!!value_var_enq) %>%                                  # outliers (needs to be 0)
        print()
      
      cat("\n Normality assumption (p>.05) \n")
      data %>%
        dplyr::group_by(!!time_var_enq, !!cond_var_enq) %>%
        rstatix::shapiro_test(!!value_var_enq) %>%                                        # normality assumption (p>.05)
        print()
      
      qq_plot <- 
        ggpubr::ggqqplot(data = data, value_var_name, ggtheme = theme_bw(), title = "QQ Plot") +
        ggplot2::facet_grid(vars(!!time_var_enq), vars(!!cond_var_enq), labeller = "label_both")    # QQ plot
      
      cat("\n Homogneity of variance assumption - Levene’s test (p>.05) \n")
      data %>%
        group_by(!!time_var_enq ) %>%
        levene_test(as.formula(paste0(value_var_name, " ~ ", cond_var_name))) %>%
        print()
      
      cat("\n Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001) \n")
      box_m(data = data[, value_var_name, drop = FALSE], group = data[, cond_var_name, drop = TRUE]) %>%
        print
    }
    
    # Two-way rmANOVA - check for interaction (ex. F(2, 22) = 30.4, p < 0.0001)
    cat("\n Two-way rmANOVA \n")
    res_aov <- 
      anova_test(data = data, dv = !!value_var_enq, wid = !!id_var_enq,               # automatically does sphericity Mauchly’s test
                 within = !!time_var_enq, between = !!cond_var_enq)
    get_anova_table(res_aov) %>%  # ges: Greenhouse-Geisser sphericity correction is automatically applied to factors violating the sphericity assumption  
      print()
    
    
    # ------------------------------------------------------------------------
    
    #- Procedure for a significant two-way interaction -
    if(posthoc_sig_interac){
      cat("\n Effect of group at each time point - One-way ANOVA\n")
      one_way <- 
        data %>%
        group_by(!!time_var_enq) %>%
        anova_test(dv = !!value_var_enq, wid = !!id_var_enq, between = !!cond_var_enq) %>%
        get_anova_table() %>%
        adjust_pvalue(method = p_adjust_method)
      one_way %>% print()
      
      cat("\n Pairwise comparisons between group levels \n")
      pwc <- 
        data %>%
        group_by(!!time_var_enq) %>%
        pairwise_t_test(as.formula(paste0(value_var_name, " ~ ", cond_var_name)), 
                        p.adjust.method = p_adjust_method)
      pwc %>% print()
      cat("\n Effect of time at each level of exercises group  - One-way ANOVA \n")
      one_way2 <- 
        data %>%
        group_by(!!cond_var_enq) %>%
        anova_test(dv = !!value_var_enq, wid = !!id_var_enq, within = !!time_var_enq) %>%
        get_anova_table() %>%
        adjust_pvalue(method = p_adjust_method)
      one_way2 %>% print()
      
      cat("\n Pairwise comparisons between time points at each group levels (we have repeated measures by time) \n")
      pwc2 <-
        data %>%
        group_by(!!cond_var_enq) %>%
        pairwise_t_test(
          as.formula(paste0(value_var_name, " ~ ", time_var_name)),     # paste formula, not quosure
          paired = TRUE,
          p.adjust.method = p_adjust_method
        )
      pwc2  %>% print()
    }
    
    #- Procedure for non-significant two-way interaction- 
    # If the interaction is not significant, you need to interpret the main effects for each of the two variables: treatment and time.
    if(posthoc_ns_interac){
      cat("\n Comparisons for treatment variable \n")
      pwc_cond <-
        data %>%
        pairwise_t_test(
          as.formula(paste0(value_var_name, " ~ ", cond_var_name)),     # paste formula, not quosure             
          paired = FALSE,
          p.adjust.method = p_adjust_method
        )
      pwc_cond %>% print()
      cat("\n Comparisons for time variable \n")
      pwc_time <-
        data %>% 
        pairwise_t_test(
          as.formula(paste0(value_var_name, " ~ ", time_var_name)),     # paste formula, not quosure
          paired = TRUE,
          p.adjust.method = p_adjust_method
        )
      pwc_time %>% print()
    }
    
    # Visualization
    bx_plot <- 
      ggboxplot(data, x = time_var_name, y = value_var_name,
                color = cond_var_name, palette = "jco")
    pwc <- 
      pwc %>% 
      add_xy_position(x = time_var_name)
    bx_plot <- 
      bx_plot + 
      stat_pvalue_manual(pwc, tip.length = 0, hide.ns = TRUE) +
      labs(
        subtitle = get_test_label(res_aov, detailed = TRUE),
        caption = get_pwc_label(pwc)
      )
    
    if(assum_check){ 
      list(qq_plot, bx_plot)
    }else{
      bx_plot
    } 
    
  }

# ex. - run on long format
# tw_mixedANOVA_func(data = anxiety, id_var = id, cond_var = group, time_var = time, value_var = score,
#                 posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)

2 Read, Clean, Recode

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Read, Clean, Recode, Unite
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

## Read files
folder <- "C:/Users/Mihai/Desktop/R Notebooks/notebooks/M2-report"
file <- "DateM2 final.xlsx"

setwd(folder)
Data_pre <- rio::import(file.path(folder, file),
                           skip = 3, which = "M2 PRE")

Data_post <- rio::import(file.path(folder, file),
                           skip = 3, which = "M2 POST")



# PRE = colnames(Data_pre); POST = colnames(Data_post) 
# cbind(PRE, POST)                                             # "s1.7" var is missing form POST -- missmatch row 12
#                                                              # also missing "s2.7" and others


# index from "DateM2.xlsx"
# index_ryff_pre <- 94:135
# index_pss_pre <- 136:149
# index_ryff_post <- 94:135 - 5
# index_pss_post <- 136:149 - 5

index_ryff_pre <- 83:124
index_pss_pre <- 125:138
index_ryff_post <- 81:122
index_pss_post <- 123:136


colnames(Data_pre)[1] <- "ID"
colnames(Data_pre)[colnames(Data_pre) == "Stres pre"] <- "VAS_stress_pre"
colnames(Data_pre)[colnames(Data_pre) == "Stres post"] <- "VAS_stress_post"
colnames(Data_pre)[index_ryff_pre] <- sprintf("ryff_%01d", seq(1, 42))
colnames(Data_pre)[index_pss_pre] <- sprintf("pss_%01d", seq(1, 14))
Data_pre <-
  Data_pre %>%
  drop_na(ID) %>%
  dplyr::mutate_if(is.character, list(~dplyr::na_if(., "na"))) 
Data_pre[index_ryff_pre] <- colstonumeric(Data_pre[index_ryff_pre])
Data_pre$pss_8[Data_pre$pss_8 == "++++++"] <- NA                           # typo
Data_pre[index_pss_pre] <- colstonumeric(Data_pre[index_pss_pre])

colnames(Data_post)[1] <- "ID"
colnames(Data_post)[colnames(Data_post) == "Stres pre"] <- "VAS_stress_pre"
colnames(Data_post)[colnames(Data_post) == "Stres post"] <- "VAS_stress_post"
colnames(Data_post)[index_ryff_post] <- sprintf("ryff_%01d", seq(1, 42))
colnames(Data_post)[index_pss_post] <- sprintf("pss_%01d", seq(1, 14))
Data_post <-
  Data_post %>%
  dplyr::mutate_if(is.character, list(~dplyr::na_if(., "na"))) 
Data_post[index_ryff_post] <- colstonumeric(Data_post[index_ryff_post])
Data_post[index_pss_post] <- colstonumeric(Data_post[index_pss_post])

# typos
# check_numeric <- as.data.frame(sapply(Data_pre[index_pss_pre], varhandle::check.numeric)) 
# sapply(check_numeric, function(x) length(which(!x)))

colnames(Data_pre)[colnames(Data_pre) == "s1.1."] <- "s1.1"
colnames(Data_post)[colnames(Data_post) == "s1.1."] <- "s1.1"

Data_post$s2.10[which(Data_post$s2.10 == ".")] <- NA
Data_post$s2.10 <- as.numeric(Data_post$s2.10)
Data_post$s3.16[which(Data_post$s3.16 == "kq")] <- NA
Data_post$s3.16 <- as.numeric(Data_post$s3.16)
## PSS-SF 14 (likert 0-4)
# Items 4, 5, 6, 7, 9, 10, and 13 are scored in reverse direction.

indexitem_revPSS <- c(4, 5, 6, 7, 9, 10, 13)

Data_pre[, index_pss_pre][indexitem_revPSS] <- ReverseCode(Data_pre[, index_pss_pre][indexitem_revPSS], tonumeric = FALSE, min = 0, max = 4)
Data_post[, index_pss_post][indexitem_revPSS] <- ReverseCode(Data_post[, index_pss_post][indexitem_revPSS], tonumeric = FALSE, min = 0, max = 4)

Data_pre$PSS <- ScoreLikert(Data_pre[, index_pss_pre], napercent = .4)
Data_post$PSS <- ScoreLikert(Data_post[, index_pss_post], napercent = .4)
  

## Ryff (likert 1-6)
# Recode negative phrased items:  3,5,10,13,14,15,16,17,18,19,23,26,27,30,31,32,34,36,39,41.
# Autonomy: 1,7,13,19,25,31,37
# Environmental mastery: 2,8,14,20,26,32,38
# Personal Growth: 3,9,15,21,27,33,39
# Positive Relations: 4,10,16,22,28,34,40
# Purpose in life: 5,11,17,23,29,35,41
# Self-acceptance: 6,12,18,24,30,36,42

indexitem_revRYFF <- c(3,5,10,13,14,15,16,17,18,19,23,26,27,30,31,32,34,36,39,41)

Data_pre[, index_ryff_pre][indexitem_revRYFF] <- ReverseCode(Data_pre[, index_ryff_pre][indexitem_revRYFF], tonumeric = FALSE, min = 1, max = 6)
Data_post[, index_ryff_post][indexitem_revRYFF] <- ReverseCode(Data_post[, index_ryff_post][indexitem_revRYFF], tonumeric = FALSE, min = 1, max = 6)

indexitem_Auto <- c(1,7,13,19,25,31,37)
indexitem_EnvM <- c(2,8,14,20,26,32,38)
indexitem_PersG <- c(3,9,15,21,27,33,39)
indexitem_PosRel <- c(4,10,16,22,28,34,40)
indexitem_PurLif <- c(5,11,17,23,29,35,41)
indexitem_SelfAc <- c(6,12,18,24,30,36,42)


Data_pre$Auto <- ScoreLikert(Data_pre[, index_ryff_pre][indexitem_Auto], napercent = .4)
Data_pre$EnvM <- ScoreLikert(Data_pre[, index_ryff_pre][indexitem_EnvM], napercent = .4)
Data_pre$PersG <- ScoreLikert(Data_pre[, index_ryff_pre][indexitem_PersG], napercent = .4)
Data_pre$PosRel <- ScoreLikert(Data_pre[, index_ryff_pre][indexitem_PosRel], napercent = .4)
Data_pre$PurLif <- ScoreLikert(Data_pre[, index_ryff_pre][indexitem_PurLif], napercent = .4)
Data_pre$SelfAc <- ScoreLikert(Data_pre[, index_ryff_pre][indexitem_SelfAc], napercent = .4)

Data_post$Auto <- ScoreLikert(Data_post[, index_ryff_post][indexitem_Auto], napercent = .4)
Data_post$EnvM <- ScoreLikert(Data_post[, index_ryff_post][indexitem_EnvM], napercent = .4)
Data_post$PersG <- ScoreLikert(Data_post[, index_ryff_post][indexitem_PersG], napercent = .4)
Data_post$PosRel <- ScoreLikert(Data_post[, index_ryff_post][indexitem_PosRel], napercent = .4)
Data_post$PurLif <- ScoreLikert(Data_post[, index_ryff_post][indexitem_PurLif], napercent = .4)
Data_post$SelfAc <- ScoreLikert(Data_post[, index_ryff_post][indexitem_SelfAc], napercent = .4)

## Save Scores
# rio::export(Data_pre[, c(1, 150:156)])
# rio::export(Data_post[, c(1, 149:155)])
# nlastcol <- 7
# rio::export(list(PRE = Data_pre[, c(1, (ncol(Data_pre)-nlastcol+1):ncol(Data_pre))], POST = Data_post[, c(1, (ncol(Data_post)-nlastcol+1):ncol(Data_post))]), 
#             "M2 PSS Ryff final.xlsx")

Data_pre$S1_Mean <- rowMeans(Data_pre[, sprintf("s1.%d", c(1:6, 8:16))], na.rm = TRUE)  # Data_pre[, grep("s1.", colnames(Data_pre))]
Data_pre$S2_Mean <- rowMeans(Data_pre[, sprintf("s2.%d", c(1:6, 8:16))], na.rm = TRUE)  # Data_pre[, grep("s2.", colnames(Data_pre))]
Data_pre$S3_Mean <- rowMeans(Data_pre[, sprintf("s3.%d", c(1:6, 8:16))], na.rm = TRUE)  # Data_pre[, grep("s3.", colnames(Data_pre))]

Data_post$S1_Mean <- rowMeans(Data_post[, sprintf("s1.%d", c(1:6, 8:16))], na.rm = TRUE)  # Data_post[, grep("s1.", colnames(Data_post))]
Data_post$S2_Mean <- rowMeans(Data_post[, sprintf("s2.%d", c(1:6, 8:16))], na.rm = TRUE)  # Data_post[, grep("s2.", colnames(Data_post))]
Data_post$S3_Mean <- rowMeans(Data_post[, sprintf("s3.%d", c(1:6, 8:16))], na.rm = TRUE)  # Data_post[, grep("s3.", colnames(Data_post))]

3 Add TR & CTRL groups

4 Unite data frames

## Number of subjects in pre
## Number of subjects in post

5 ANCOVA Post

5.1 PSS

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F           p p<.05      ges

1 Cond 1 55 0.012 0.914000000 0.000215 2 Pre 1 55 33.434 0.000000361 * 0.378000 3 Cond:Pre 1 55 2.739 0.104000000 0.047000

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 32.428 0.000000475 * 0.367000 2 Cond 1 56 0.011 0.915000000 0.000205

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.2 Auto

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd          F                p p<.05        ges

1 Cond 1 55 0.0410000 0.84100000000000 0.00073700 2 Pre 1 55 74.0980000 0.00000000000901 * 0.57400000 3 Cond:Pre 1 55 0.0000569 0.99400000000000 0.00000104

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 75.445 0.00000000000583 * 0.574000 2 Cond 1 56 0.041 0.84000000000000 0.000737

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.3 EnvM

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F           p p<.05      ges

1 Cond 1 55 0.018 0.895000000 0.000321 2 Pre 1 55 34.023 0.000000299 * 0.382000 3 Cond:Pre 1 55 3.189 0.080000000 0.055000

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 32.743 0.000000429 * 0.369000 2 Cond 1 56 0.017 0.897000000 0.000303

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.4 PersG

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F          p p<.05      ges

1 Cond 1 55 0.053 0.81800000 0.000968 2 Pre 1 55 29.116 0.00000149 * 0.346000 3 Cond:Pre 1 55 0.731 0.39600000 0.013000

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 29.257 0.00000136 * 0.343000 2 Cond 1 56 0.054 0.81800000 0.000955

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.5 PosRel

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F               p p<.05   ges

1 Cond 1 55 0.092 0.7620000000000 0.002 2 Pre 1 55 64.079 0.0000000000856 * 0.538 3 Cond:Pre 1 55 1.048 0.3110000000000 0.019

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 64.024 0.0000000000769 * 0.533 2 Cond 1 56 0.092 0.7620000000000 0.002

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.6 PurLif

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd          F           p p<.05         ges

1 Cond 1 55 0.2230000 0.639000000 0.004000000 2 Pre 1 55 37.4200000 0.000000104 * 0.405000000 3 Cond:Pre 1 55 0.0000161 0.997000000 0.000000293

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 38.101 0.0000000795 * 0.405 2 Cond 1 56 0.227 0.6360000000 0.004

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.7 SelfAc

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F               p p<.05       ges

1 Cond 1 55 0.005 0.9430000000000 0.0000941 2 Pre 1 55 69.887 0.0000000000227 * 0.5600000 3 Cond:Pre 1 55 1.004 0.3210000000000 0.0180000

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 69.881 0.0000000000199 * 0.5550000 2 Cond 1 56 0.005 0.9430000000000 0.0000924

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.8 S1_Mean

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F               p p<.05      ges

1 Cond 1 55 0.024 0.8780000000000 0.000431 2 Pre 1 55 72.493 0.0000000000128 * 0.569000 3 Cond:Pre 1 55 0.022 0.8830000000000 0.000400

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 73.781 0.00000000000836 * 0.569000 2 Cond 1 56 0.024 0.87700000000000 0.000431

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.9 S2_Mean

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F                p p<.05   ges

1 Cond 1 55 2.077 0.15500000000000 0.036 2 Pre 1 55 74.964 0.00000000000748 * 0.577 3 Cond:Pre 1 55 1.310 0.25700000000000 0.023

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 74.551 0.00000000000707 * 0.571 2 Cond 1 56 2.066 0.15600000000000 0.036

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.10 S3_Mean

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F                 p p<.05   ges

1 Cond 1 55 3.145 0.082000000000000 0.054 2 Pre 1 55 93.246 0.000000000000192 * 0.629 3 Cond:Pre 1 55 0.153 0.697000000000000 0.003

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 94.678 0.000000000000122 * 0.628 2 Cond 1 56 3.193 0.079000000000000 0.054

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.11 Vas_Diff

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd     F     p p<.05   ges

1 Cond 1 53 0.362 0.550 0.007 2 Pre 1 53 9.515 0.003 * 0.152 3 Cond:Pre 1 53 1.008 0.320 0.019

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 54 9.514 0.003 * 0.150 2 Cond 1 54 0.362 0.550 0.007

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

5.12 Vas_Mean

Linearity assumptionLinearity assumption (linear relationship between pre-test and post-test for each group)

Homogeneity of regression slopes (interaction term is n.s.) ANOVA Table (type II tests)

Effect DFn DFd      F        p p<.05      ges

1 Cond 1 55 0.022 0.884000 0.000392 2 Pre 1 55 15.386 0.000245 * 0.219000 3 Cond:Pre 1 55 0.257 0.614000 0.005000

Normality of residuals (Model diagnostics & Shapiro Wilk)

Inspect the model diagnostic metrics

Normality of residuals (Shapiro Wilk p>.05)

Homogeneity of variances (Levene’s test p>.05)

Outliers (needs to be 0)

ANCOVAPost ANOVA Table (type II tests)

Effect DFn DFd F p p<.05 ges 1 Pre 1 56 15.593 0.000222 * 0.21800 2 Cond 1 56 0.022 0.883000 0.00039

Pairwise comparisons

Display the adjusted means of each group, also called as the estimated marginal means (emmeans)

[[1]]

[[2]]

6 Mixed ANOVA

6.1 PSS

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05      ges

1 Cond 1 57 0.918 0.342 0.013000 2 PrePost 1 57 1.092 0.300 0.004000 3 Cond:PrePost 1 57 0.229 0.634 0.000801

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.2 Auto

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05        ges

1 Cond 1 57 0.513 0.477 0.00800000 2 PrePost 1 57 0.493 0.485 0.00100000 3 Cond:PrePost 1 57 0.003 0.954 0.00000739

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.3 EnvM

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05      ges

1 Cond 1 57 0.227 0.636 0.003000 2 PrePost 1 57 0.932 0.338 0.003000 3 Cond:PrePost 1 57 0.099 0.754 0.000346

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.4 PersG

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05       ges

1 Cond 1 57 0.134 0.716 0.0020000 2 PrePost 1 57 1.153 0.287 0.0040000 3 Cond:PrePost 1 57 0.014 0.908 0.0000496

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.5 PosRel

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05      ges

1 Cond 1 57 0.037 0.847 0.000563 2 PrePost 1 57 0.236 0.629 0.000584 3 Cond:PrePost 1 57 0.124 0.726 0.000308

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.6 PurLif

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05      ges

1 Cond 1 57 0.678 0.414 0.010000 2 PrePost 1 57 0.286 0.595 0.000916 3 Cond:PrePost 1 57 0.042 0.838 0.000134

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.7 SelfAc

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05      ges

1 Cond 1 57 1.128 0.293 0.017000 2 PrePost 1 57 0.960 0.331 0.002000 3 Cond:PrePost 1 57 0.205 0.653 0.000458

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.8 S1_Mean

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd      F     p p<.05      ges

1 Cond 1 57 2.845 0.097 0.042000 2 PrePost 1 57 11.041 0.002 * 0.023000 3 Cond:PrePost 1 57 0.118 0.732 0.000256

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.9 S2_Mean

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd      F         p p<.05   ges

1 Cond 1 57 2.952 0.0910000 0.043 2 PrePost 1 57 17.549 0.0000983 * 0.037 3 Cond:PrePost 1 57 1.569 0.2150000 0.003

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.10 S3_Mean

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05   ges

1 Cond 1 57 1.267 0.265 0.019 2 PrePost 1 57 3.754 0.058 0.007 3 Cond:PrePost 1 57 1.881 0.176 0.003

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.11 Vas_Diff

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd       F     p p<.05         ges

1 Cond 1 55 1.01900 0.317 0.013000000 2 PrePost 1 55 9.60500 0.003 * 0.051000000 3 Cond:PrePost 1 55 0.00007 0.993 0.000000391

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]

6.12 Vas_Mean

Outliers

Normality assumption (p>.05)

Homogneity of variance assumption - Levene’s test (p>.05)

Homogeneity of covariances assumption - Box’s test of equality of covariance matrices (p>.001)

Two-way rmANOVA ANOVA Table (type III tests)

    Effect DFn DFd     F     p p<.05      ges

1 Cond 1 57 0.459 0.501 0.006000 2 PrePost 1 57 0.379 0.541 0.002000 3 Cond:PrePost 1 57 0.029 0.866 0.000136

Effect of group at each time point - One-way ANOVA

Pairwise comparisons between group levels

Effect of time at each level of exercises group - One-way ANOVA

Pairwise comparisons between time points at each group levels (we have repeated measures by time)

Comparisons for treatment variable

Comparisons for time variable

[[1]]

[[2]]


7 Session Info

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] rlang_0.4.6                emmeans_1.4.5              rio_0.5.16                 scales_1.1.0               ggpubr_0.2.5               magrittr_1.5              
 [7] tadaatoolbox_0.16.1        summarytools_0.8.8         rstatix_0.5.0              broom_0.5.6                PerformanceAnalytics_1.5.2 xts_0.11-2                
[13] zoo_1.8-4                  psych_1.9.12.31            forcats_0.5.0              stringr_1.4.0              dplyr_0.8.5                purrr_0.3.3               
[19] readr_1.3.1                tidyr_1.0.2                tibble_3.0.0               ggplot2_3.3.0              tidyverse_1.3.0            papaja_0.1.0.9842         
[25] pacman_0.5.1              

loaded via a namespace (and not attached):
 [1] TH.data_1.0-9      colorspace_1.4-1   ggsignif_0.4.0     pryr_0.1.4         ellipsis_0.3.0     estimability_1.3   fs_1.4.1           rstudioapi_0.11   
 [9] farver_2.0.3       fansi_0.4.1        mvtnorm_1.1-0      lubridate_1.7.4    xml2_1.3.1         codetools_0.2-16   splines_3.6.1      mnormt_1.5-6      
[17] knitr_1.28         pixiedust_0.8.6    polynom_1.3-9      jsonlite_1.6.1     dbplyr_1.4.3       compiler_3.6.1     httr_1.4.1         backports_1.1.6   
[25] assertthat_0.2.1   Matrix_1.2-17      cli_2.0.2          htmltools_0.4.0    tools_3.6.1        coda_0.19-2        gtable_0.3.0       glue_1.4.0        
[33] Rcpp_1.0.4.6       carData_3.0-2      cellranger_1.1.0   vctrs_0.2.4        nlme_3.1-140       xfun_0.13          openxlsx_4.1.0     rvest_0.3.5       
[41] lifecycle_0.2.0    MASS_7.3-51.4      hms_0.5.3          parallel_3.6.1     sandwich_2.5-0     expm_0.999-3       pwr_1.2-2          curl_4.3          
[49] gridExtra_2.3      pander_0.6.3       stringi_1.4.6      nortest_1.0-4      boot_1.3-22        zip_1.0.0          pkgconfig_2.0.3    matrixStats_0.54.0
[57] bitops_1.0-6       lattice_0.20-38    labeling_0.3       rapportools_1.0    tidyselect_1.0.0   ggsci_2.9          plyr_1.8.6         R6_2.4.1          
[65] DescTools_0.99.34  generics_0.0.2     multcomp_1.4-8     DBI_1.0.0          pillar_1.4.3       haven_2.2.0        foreign_0.8-71     withr_2.1.2       
[73] mgcv_1.8-28        survival_2.44-1.1  abind_1.4-5        RCurl_1.95-4.11    modelr_0.1.6       crayon_1.3.4       car_3.0-7          viridis_0.5.1     
[81] grid_3.6.1         readxl_1.3.1       data.table_1.12.8  reprex_0.3.0       digest_0.6.25      xtable_1.8-4       munsell_0.5.0      viridisLite_0.3.0 
[89] quadprog_1.5-5    
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gTTIiIA0Kc3VidGl0bGU6ICJSZXBvcnQiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICAgICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgICAgICAgICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgICAgICAgICAgZm9udC1mYW1pbHk6IEFyaWFsDQogICAgICAgICAgICBmaWdfd2lkdGg6IDEwDQogICAgICAgICAgICBmaWdfaGVpZ2h0OiA5DQogICAgIyBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICAjIGZvbnRzaXplOiAxMXB0DQogICAgICAgICAgICAjIGdlb21ldHJ5OiBtYXJnaW49MWluDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNw0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA2DQogICAgICAgICAgICAjIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgIyBnaXRodWJfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIGh0bWxfcHJldmlldzogZmFsc2UNCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA1DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDUNCiAgICAgICAgICAgICMgZGV2OiBqcGVnDQotLS0NCg0KDQo8IS0tIFNldHVwIC0tPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZXJyb3IgPSBUUlVFLA0KICBlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gVFJVRSAgICAgICAjIGVjaG8gPSBGYWxzZSBmb3IgZ2l0aHViX2RvY3VtZW50LCBidXQgd2lsbCBiZSBmb2xkZWQgaW4gaHRtbF9ub3RlYm9vaw0KKQ0KDQojIEdlbmVyYWwgUiBvcHRpb25zIGFuZCBpbmZvDQpzZXQuc2VlZCgxMTEpICAgICAgICAgICAgICAgIyBpbiBjYXNlIHdlIHVzZSByYW5kb21pemVkIHByb2NlZHVyZXMgICAgICAgDQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgICAgICAgIyBwb3NpdGl2ZSB2YWx1ZXMgYmlhcyB0b3dhcmRzIGZpeGVkIGFuZCBuZWdhdGl2ZSB0b3dhcmRzIHNjaWVudGlmaWMgbm90YXRpb24NCg0KIyBMb2FkIHBhY2thZ2VzDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFja2FnZXMgPC0gYygNCiAgInBhcGFqYSIsDQogICJ0aWR5dmVyc2UiLCAgICAgICANCiAgInBzeWNoIiwgIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgICAgICAgICAgDQogICJicm9vbSIsICJyc3RhdGl4IiwNCiAgInN1bW1hcnl0b29scyIsICJ0YWRhYXRvb2xib3giLCAgICAgICAgICAgDQogICJnZ3Bsb3QyIiwgImdncHViciIsICJzY2FsZXMiLCAgICAgICAgDQogICJyaW8iLA0KICAiZ2dwdWJyIiwgInJzdGF0aXgiLCAiYnJvb20iLCAiZW1tZWFucyIsICJybGFuZyINCiAgIyAsIC4uLg0KKQ0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY21hbjo6cF9sb2FkKGNoYXIgPSBwYWNrYWdlcykNCg0KIyBUaGVtZXMgZm9yIGdncGxvdDIgcGxvdGluZyAoaGVyZSB1c2VkIEFQQSBzdHlsZSkNCnRoZW1lX3NldCh0aGVtZV9hcGEoKSkNCmBgYA0KDQoNCg0KDQoNCjwhLS0gUmVwb3J0IC0tPg0KDQojIERlZmluZSBmdW5jdGlvbnMNCg0KYGBge3IgZGVmX2Z1bmN9DQojIyBEZWZpbmUgZnVuY3Rpb24gdGhhdCByZWNvZGVzIHRvIG51bWVyaWMsIGJ1dCB3YXRjaGVzIG91dCB0byBjb2VyY2lvbiB0byBub3QgaW50cm9kdWNlIE5Bcw0KY29sc3RvbnVtZXJpYyA8LSBmdW5jdGlvbihkZil7DQogIHRyeUNhdGNoKHsNCiAgICBkZl9udW0gPC0gYXMuZGF0YS5mcmFtZSgNCiAgICAgIGxhcHBseShkZiwNCiAgICAgICAgICAgICBmdW5jdGlvbih4KSB7IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgpKX0pKSANCiAgfSx3YXJuaW5nID0gZnVuY3Rpb24oc3RvcF9vbl93YXJuaW5nKSB7DQogICAgbWVzc2FnZSgiU3RvcGVkIHRoZSBleGVjdXRpb24gb2YgbnVtZXJpYyBjb252ZXJzaW9uOiAiLCBjb25kaXRpb25NZXNzYWdlKHN0b3Bfb25fd2FybmluZykpDQogIH0pIA0KfQ0KIyMNCiMjIERlZmluZSBmdW5jdGlvbiB0aGF0IHJldmVyc2UgY29kZXMgaXRlbXMNClJldmVyc2VDb2RlIDwtIGZ1bmN0aW9uKGRmLCB0b251bWVyaWMgPSBGQUxTRSwgbWluID0gTlVMTCwgbWF4ID0gTlVMTCkgew0KICBpZih0b251bWVyaWMpIGRmIDwtIGNvbHN0b251bWVyaWMoZGYpDQogIGRmIDwtIChtYXggKyBtaW4pIC0gZGYNCn0NCiMjDQojIyBEZWZpbmUgZnVuY3Rpb24gdGhhdCBzY29yZXMgb25seSByb3dzIHdpdGggbGVzcyB0aGFuIDEwJSBOQXMgKHJldHVybnMgTkEgaWYgYWxsIG9yIGFib3ZlIHRocmVzaG9sZCBwZXJjZW50YWdlIG9mIHJvd3MgYXJlIE5BKTsgY2FuIHJldmVyc2UgY29kZSBpZiB2ZWN0b3Igb2YgY29sdW1uIGluZGV4ZXMgYW5kIG1pbiwgbWF4IGFyZSBwcm92aWRlZC4NClNjb3JlTGlrZXJ0IDwtIGZ1bmN0aW9uKGRmLCBuYXBlcmNlbnQgPSAuMSwgdG9udW1lcmljID0gRkFMU0UsIHJldmVyc2Vjb2xzID0gTlVMTCwgbWluID0gTlVMTCwgbWF4ID0gTlVMTCkgew0KICByZXZlcnNlX2xpc3QgPC0gbGlzdChyZXZlcnNlY29scyA9IHJldmVyc2Vjb2xzLCBtaW4gPSBtaW4sIG1heCA9IG1heCkNCiAgcmV2ZXJzZV9jaGVjayA8LSAhc2FwcGx5KHJldmVyc2VfbGlzdCwgaXMubnVsbCkNCiAgDQogICMgUmVjb2RlIHRvIG51bWVyaWMsIGJ1dCB3YXRjaCBvdXQgdG8gY29lcmNpb24gdG8gbm90IGludHJvZHVjZSBOQXMNCiAgY29sc3RvbnVtZXJpYyA8LSBmdW5jdGlvbihkZil7DQogICAgdHJ5Q2F0Y2goew0KICAgICAgZGZfbnVtIDwtIGFzLmRhdGEuZnJhbWUoDQogICAgICAgIGxhcHBseShkZiwNCiAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHsgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeCkpfSkpIA0KICAgIH0sd2FybmluZyA9IGZ1bmN0aW9uKHN0b3Bfb25fd2FybmluZykgew0KICAgICAgbWVzc2FnZSgiU3RvcGVkIHRoZSBleGVjdXRpb24gb2YgbnVtZXJpYyBjb252ZXJzaW9uOiAiLCBjb25kaXRpb25NZXNzYWdlKHN0b3Bfb25fd2FybmluZykpDQogICAgfSkgDQogIH0NCiAgDQogIGlmKHRvbnVtZXJpYykgZGYgPC0gY29sc3RvbnVtZXJpYyhkZikNCiAgDQogIGlmKGFsbChyZXZlcnNlX2NoZWNrKSl7DQogICAgZGZbICxyZXZlcnNlY29sc10gPC0gKG1heCArIG1pbikgLSBkZlsgLHJldmVyc2Vjb2xzXQ0KICB9ZWxzZSBpZihhbnkocmV2ZXJzZV9jaGVjaykpew0KICAgIHN0b3AoIkluc3VmaWNpZW50IGluZm8gZm9yIHJldmVyc2luZy4gUGxlYXNlIHByb3ZpZGU6ICIsIHBhc3RlKG5hbWVzKHJldmVyc2VfbGlzdClbIXJldmVyc2VfY2hlY2tdLCBjb2xsYXBzZSA9ICIsICIpKQ0KICB9DQogIA0KICBpZmVsc2Uocm93U3Vtcyhpcy5uYShkZikpID4gbmNvbChkZikgKiBuYXBlcmNlbnQsDQogICAgICAgICBOQSwNCiAgICAgICAgIHJvd1N1bXMoZGYsIG5hLnJtID0gVFJVRSkgKiBOQSBeIChyb3dTdW1zKCFpcy5uYShkZikpID09IDApDQogICkNCn0NCiMjDQpgYGANCg0KDQpgYGB7ciBkZWZfZnVuY190dGVzdCwgaGlkZT1UUlVFfQ0KIyMgRnVuYyB0IHRlc3Qgc2kgYm94cGxvdCBzaW1wbHUNCmZ1bmNfdF9ib3ggPC0gZnVuY3Rpb24oZGYsIGluZCwgcHJlX3ZhciwgcG9zdF92YXIpew0KICB2YXJzIDwtIGMoaW5kLCBwcmVfdmFyLCBwb3N0X3ZhcikgICAgICAgICAgICAgICAgIyB0byBhdm9pZCBuZXcgdGlkeXZlcnNlIGVycm9yIG9mIGFtYmlndWl0eSBkdWUgdG8gZXh0ZXJuYWwgdmVjdG9zDQogIGRmX21vZGlmIDwtDQogICAgZGYgJT4lDQogICAgZHBseXI6OnNlbGVjdCh0aWR5c2VsZWN0OjphbGxfb2YodmFycykpICU+JSANCiAgICB0aWR5cjo6ZHJvcF9uYSgpICU+JQ0KICAgIGdhdGhlcih0aWR5c2VsZWN0OjphbGxfb2YocHJlX3ZhciksIHRpZHlzZWxlY3Q6OmFsbF9vZihwb3N0X3ZhciksIGtleSA9ICJDb25kIiwgdmFsdWUgPSAidmFsdWUiKSAlPiUgDQogICAgbXV0YXRlX2F0KHZhcnMoYygxLCAyKSksIGFzLmZhY3RvcikgJT4lIA0KICAgIG11dGF0ZShDb25kID0gZmFjdG9yKENvbmQsIGxldmVscyA9IGMocHJlX3ZhciwgcG9zdF92YXIpKSkgDQogIA0KICBzdGF0X2NvbXAgPC0gZ2dwdWJyOjpjb21wYXJlX21lYW5zKHZhbHVlIH4gQ29uZCwgZGF0YSA9IGRmX21vZGlmLCBtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSkNCiAgDQogIHN0YXRfY29tcDIgPC0NCiAgICBkZl9tb2RpZiAlPiUgDQogICAgZG8odGlkeSh0LnRlc3QoLiR2YWx1ZSB+IC4kQ29uZCwNCiAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9LikpKQ0KICANCiAgcGxvdCA8LSANCiAgICBnZ3B1YnI6OmdncGFpcmVkKGRmX21vZGlmLCB4ID0gIkNvbmQiLCB5ID0gInZhbHVlIiwgaWQgPSBpbmQsIA0KICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiQ29uZCIsIGxpbmUuY29sb3IgPSAiZ3JheSIsIGxpbmUuc2l6ZSA9IDAuNCwNCiAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNGQzRFMDciKSwgbGVnZW5kID0gIm5vbmUiKSArDQogICAgICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCAgY29sb3VyID0gImRhcmtyZWQiKSArDQogICAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgbGFiZWwueCA9IGFzLm51bWVyaWMoZGZfbW9kaWYkQ29uZCktMC40LCBsYWJlbC55ID0gbWF4KGRmX21vZGlmJHZhbHVlKSswLjUpICsgDQogICAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgbGFiZWwgPSAicC5zaWduaWYiLCBjb21wYXJpc29ucyA9IGxpc3QoYyhwcmVfdmFyLCBwb3N0X3ZhcikpKQ0KICANCiAgY2F0KHBhc3RlMCgiIyMjIyAiLCBwcmVfdmFyLCAiICIsIHBvc3RfdmFyLCAiXG4iLCAiXG4iKSkNCiAgcHJpbnQoc3RhdF9jb21wKQ0KICBwcmludChzdGF0X2NvbXAyKQ0KICBwcmludChwbG90KQ0KfQ0KYGBgDQoNCg0KYGBge3IgZGVmX2Z1bmNfQU5DT1ZBUG9zdH0NCiMgbGlicmFyeSh0aWR5dmVyc2UpDQojIGxpYnJhcnkoZ2dwdWJyKQ0KIyBsaWJyYXJ5KHJzdGF0aXgpDQojIGxpYnJhcnkoYnJvb20pDQojIGxpYnJhcnkoZW1tZWFucykNCiMgbGlicmFyeShybGFuZykNCg0KDQojIEZ1bmN0aW9uIEFOQ09WQVBvc3QNCiMgVGFrZXMgTG9uZyBEYXRhDQpBTkNPVkFQb3N0X2Z1bmMgPC0gDQogIGZ1bmN0aW9uKGRhdGEsIGlkX3ZhciwgDQogICAgICAgICAgIHRpbWVfdmFyLCBwcmVfbGFiZWwsIHBvc3RfbGFiZWwsDQogICAgICAgICAgIHZhbHVlX3ZhciA9IHNjb3JlcywgY29uZF92YXIsIA0KICAgICAgICAgICBhc3N1bV9jaGVjayA9IFRSVUUsIHBvc3Rob2MgPSBUUlVFLCANCiAgICAgICAgICAgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKXsNCiAgDQogIGlkX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKGlkX3ZhcikNCiAgaWRfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUoaWRfdmFyX2VucSkgICAgDQogIHRpbWVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8odGltZV92YXIpDQogIHRpbWVfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUodGltZV92YXJfZW5xKQ0KICBwcmVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8ocHJlX2xhYmVsKQ0KICBwcmVfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUocHJlX3Zhcl9lbnEpICANCiAgcG9zdF92YXJfZW5xIDwtIHJsYW5nOjplbnF1byhwb3N0X2xhYmVsKQ0KICBwb3N0X3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHBvc3RfdmFyX2VucSkNCiAgY29uZF92YXJfZW5xIDwtIHJsYW5nOjplbnF1byhjb25kX3ZhcikNCiAgY29uZF92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZShjb25kX3Zhcl9lbnEpDQogIHZhbHVlX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKHZhbHVlX3ZhcikNCiAgdmFsdWVfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUodmFsdWVfdmFyX2VucSkgDQogIA0KICBkYXRhX3dpZGVyIDwtDQogICAgZGF0YSAlPiUNCiAgICBkcGx5cjo6c2VsZWN0KCEhaWRfdmFyX2VucSwgISF0aW1lX3Zhcl9lbnEsICEhY29uZF92YXJfZW5xLCAhIXZhbHVlX3Zhcl9lbnEpICU+JQ0KICAgIHNwcmVhZChrZXkgPSB0aW1lX3Zhcl9uYW1lLCB2YWx1ZSA9IHZhbHVlX3Zhcl9uYW1lKSAjICU+JSAgICAgIyBpZiBuZWVkIHRvIGNvbXB1dGUgY2hhbmdlIHNjb3JlIHN0YXRpc3RpY3MgZ28gZnJvbSBoZXJlDQogICAgIyBtdXRhdGUoZGlmZmVyZW5jZSA9ICEhcG9zdF92YXJfZW5xIC0gISFwcmVfdmFyX2VucSkgIA0KICAgIA0KICAjIEFzc3VtcHRpb25zDQogIGlmKGFzc3VtX2NoZWNrKXsNCiAgY2F0KCJcbiBMaW5lYXJpdHkgYXNzdW1wdGlvbkxpbmVhcml0eSBhc3N1bXB0aW9uIChsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gcHJlLXRlc3QgYW5kIHBvc3QtdGVzdCBmb3IgZWFjaCBncm91cCkgXG4iKQ0KICAjIENyZWF0ZSBhIHNjYXR0ZXIgcGxvdCBiZXR3ZWVuIHRoZSBjb3ZhcmlhdGUgKGkuZS4sIHByZXRlc3QpIGFuZCB0aGUgb3V0Y29tZSB2YXJpYWJsZSAoaS5lLiwgcG9zdHRlc3QpDQogIHNjYXR0ZXJfbGluIDwtICANCiAgICBnZ3NjYXR0ZXIoZGF0YV93aWRlciwgeCA9IHByZV92YXJfbmFtZSwgeSA9IHBvc3RfdmFyX25hbWUsIGNvbG9yID0gY29uZF92YXJfbmFtZSwgDQogICAgICAgICAgICAgIGFkZCA9ICJyZWcubGluZSIsIHRpdGxlID0gIkxpbmVhcml0eSBhc3N1bXB0aW9uIikgKw0KICAgICAgc3RhdF9yZWdsaW5lX2VxdWF0aW9uKGFlcyhsYWJlbCA9ICBwYXN0ZSguLmVxLmxhYmVsLi4sIC4ucnIubGFiZWwuLiwgc2VwID0gIn5+fn4iKSwgY29sb3IgPSAhIWNvbmRfdmFyX2VucSkpDQogIA0KICBjYXQoIlxuIEhvbW9nZW5laXR5IG9mIHJlZ3Jlc3Npb24gc2xvcGVzIChpbnRlcmFjdGlvbiB0ZXJtIGlzIG4ucy4pIFxuIikNCiAgZGF0YV93aWRlciAlPiUgDQogICAgYW5vdmFfdGVzdChhcy5mb3JtdWxhKHBhc3RlMChwb3N0X3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSwgIiAqICIsIHByZV92YXJfbmFtZSkpKSAlPiUgDQogICAgcHJpbnQoKSAgIA0KICANCiAgY2F0KCJcbiBOb3JtYWxpdHkgb2YgcmVzaWR1YWxzIChNb2RlbCBkaWFnbm9zdGljcyAmIFNoYXBpcm8gV2lsaykgXG4iKQ0KICAjIEZpdCB0aGUgbW9kZWwsIHRoZSBjb3ZhcmlhdGUgZ29lcyBmaXJzdA0KICBtb2RlbCA8LSANCiAgICBsbShhcy5mb3JtdWxhKHBhc3RlMChwb3N0X3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSwgIiArICIsIHByZV92YXJfbmFtZSkpLA0KICAgICAgIGRhdGEgPSBkYXRhX3dpZGVyKQ0KICBjYXQoIlxuIEluc3BlY3QgdGhlIG1vZGVsIGRpYWdub3N0aWMgbWV0cmljcyBcbiIpDQogIG1vZGVsLm1ldHJpY3MgPC0gDQogICAgYXVnbWVudChtb2RlbCkgJT4lDQogICAgZHBseXI6OnNlbGVjdCgtLmhhdCwgLS5zaWdtYSwgLS5maXR0ZWQsIC0uc2UuZml0KSAgJT4lICAgICMgUmVtb3ZlIGRldGFpbHMNCiAgICBwcmludCgpDQogIGNhdCgiXG4gTm9ybWFsaXR5IG9mIHJlc2lkdWFscyAoU2hhcGlybyBXaWxrIHA+LjA1KSBcbiIpDQogIHNoYXBpcm9fdGVzdChtb2RlbC5tZXRyaWNzJC5yZXNpZCkgJT4lIA0KICAgIHByaW50KCkNCiAgDQogIGNhdCgiXG4gSG9tb2dlbmVpdHkgb2YgdmFyaWFuY2VzIChMZXZlbmXigJlzIHRlc3QgcD4uMDUpIFxuIikNCiAgbW9kZWwubWV0cmljcyAlPiUgDQogICAgbGV2ZW5lX3Rlc3QoYXMuZm9ybXVsYShwYXN0ZTAoIi5yZXNpZCIsICIgfiAiLCBjb25kX3Zhcl9uYW1lKSkgKSAlPiUgICAgIA0KICAgIHByaW50KCkNCiAgDQogIGNhdCgiXG4gT3V0bGllcnMgKG5lZWRzIHRvIGJlIDApIFxuIikNCiAgbW9kZWwubWV0cmljcyAlPiUgDQogICAgZmlsdGVyKGFicyguc3RkLnJlc2lkKSA+IDMpICU+JQ0KICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogICAgcHJpbnQoKQ0KICANCiAgfQ0KICANCiAgY2F0KCJcbiBBTkNPVkFQb3N0IFxuIikNCiAgcmVzX2FuY292YSA8LSANCiAgICBkYXRhX3dpZGVyICU+JSANCiAgICBhbm92YV90ZXN0KGFzLmZvcm11bGEocGFzdGUwKHBvc3RfdmFyX25hbWUsICIgfiAiLCAgcHJlX3Zhcl9uYW1lLCAiICsgIiwgY29uZF92YXJfbmFtZSkpKSAgICAgICAjIHRoZSBjb3ZhcmlhdGUgbmVlZHMgdG8gYmUgZmlyc3QgdGVybSANCiAgZ2V0X2Fub3ZhX3RhYmxlKHJlc19hbmNvdmEpICU+JSBwcmludCgpDQogIA0KICBjYXQoIlxuIFBhaXJ3aXNlIGNvbXBhcmlzb25zIFxuIikNCiAgcHdjIDwtIA0KICAgIGRhdGFfd2lkZXIgJT4lIA0KICAgIGVtbWVhbnNfdGVzdChhcy5mb3JtdWxhKHBhc3RlMChwb3N0X3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSkpLCAgICAgICANCiAgICAgICAgICAgICAgICAgY292YXJpYXRlID0gISFwcmVfdmFyX2VucSwNCiAgICAgICAgICAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kKQ0KICBwd2MgJT4lIHByaW50KCkNCiAgY2F0KCJcbiBEaXNwbGF5IHRoZSBhZGp1c3RlZCBtZWFucyBvZiBlYWNoIGdyb3VwLCBhbHNvIGNhbGxlZCBhcyB0aGUgZXN0aW1hdGVkIG1hcmdpbmFsIG1lYW5zIChlbW1lYW5zKSBcbiIpDQogIGdldF9lbW1lYW5zKHB3YykgJT4lIHByaW50KCkNCiAgDQogICMgVmlzdWFsaXphdGlvbjogbGluZSBwbG90cyB3aXRoIHAtdmFsdWVzDQogIHB3YyA8LSANCiAgICBwd2MgJT4lIA0KICAgIGFkZF94eV9wb3NpdGlvbih4ID0gY29uZF92YXJfbmFtZSwgZnVuID0gIm1lYW5fc2UiKQ0KICANCiAgbGluZV9wbG90IDwtIA0KICAgIGdnbGluZShnZXRfZW1tZWFucyhwd2MpLCB4ID0gY29uZF92YXJfbmFtZSwgeSA9ICJlbW1lYW4iKSArDQogICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gY29uZi5sb3csIHltYXggPSBjb25mLmhpZ2gpLCB3aWR0aCA9IDAuMikgKyANCiAgICAgIHN0YXRfcHZhbHVlX21hbnVhbChwd2MsIGhpZGUubnMgPSBUUlVFLCB0aXAubGVuZ3RoID0gRkFMU0UpICsNCiAgICAgIGxhYnMoc3VidGl0bGUgPSBnZXRfdGVzdF9sYWJlbChyZXNfYW5jb3ZhLCBkZXRhaWxlZCA9IFRSVUUpLA0KICAgICAgICAgICBjYXB0aW9uID0gZ2V0X3B3Y19sYWJlbChwd2MpKQ0KICANCiAgaWYoYXNzdW1fY2hlY2spew0KICAgIGxpc3Qoc2NhdHRlcl9saW4sIGxpbmVfcGxvdCkNCiAgfWVsc2V7DQogICAgbGluZV9wbG90DQogIH0NCiAgDQp9DQoNCiMgZXguDQojIEFOQ09WQVBvc3RfZnVuYyhuZXdfYW54aWV0eSwgdGltZV92YXIgPSB0aW1lLCBwcmVfbGFiZWwgPSBwcmV0ZXN0LCBwb3N0X2xhYmVsID0gcG9zdHRlc3QsDQojICAgICAgICAgICB2YWx1ZV92YXIgPSBzY29yZXMsIGNvbmRfdmFyID0gZ3JvdXAsIGFzc3VtX2NoZWNrID0gVFJVRSwgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KYGBgDQoNCg0KYGBge3IgZGVmX2Z1bmNfbWl4ZWRBTk9WQX0NCiMgbGlicmFyeSh0aWR5dmVyc2UpDQojIGxpYnJhcnkoZ2dwdWJyKQ0KIyBsaWJyYXJ5KHJzdGF0aXgpDQojIGxpYnJhcnkocmxhbmcpDQoNCiMgRGVmaW5lIEZ1bmN0aW9uIGZvciBNaXhlZCBBbm92YQ0KdHdfbWl4ZWRBTk9WQV9mdW5jIDwtIA0KICBmdW5jdGlvbihkYXRhLCBpZF92YXIsIGNvbmRfdmFyLCB0aW1lX3ZhciwgdmFsdWVfdmFyLCANCiAgICAgICAgICAgYXNzdW1fY2hlY2sgPSBUUlVFLCBwb3N0aG9jX3NpZ19pbnRlcmFjID0gRkFMU0UsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IEZBTFNFLA0KICAgICAgICAgICBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpew0KICAgIA0KICAgICMgaW5wdXQgZGF0YWZyYW1lIG5lZWRzIHRvIGhhdmUgY29sdW1ucyBuYW1lcyBkaWZmcmVudCBmcm9tICJ2YXJpYWJsZSIgYW5kICJ2YWx1ZSIgYmVjYXVzZSBpdCBjb2xsaWRlcyB3aXRoIHJzdGF0aXg6OnNoYXBpcm9fdGVzdA0KICAgIA0KICAgIGlkX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKGlkX3ZhcikgIA0KICAgIGNvbmRfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8oY29uZF92YXIpDQogICAgY29uZF92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZShjb25kX3Zhcl9lbnEpDQogICAgdGltZV92YXJfZW5xIDwtIHJsYW5nOjplbnF1byh0aW1lX3ZhcikNCiAgICB0aW1lX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHRpbWVfdmFyX2VucSkNCiAgICB2YWx1ZV92YXJfZW5xIDwtIHJsYW5nOjplbnF1byh2YWx1ZV92YXIpDQogICAgdmFsdWVfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUodmFsdWVfdmFyX2VucSkNCiAgICANCiAgICBkYXRhIDwtICAgICAgICAgICAgICAgICAgIyBuZWVkIHRvIHN1YnNldCBiZWN1YXNlIG9mIHN0cmFuZ2UgY29udHJhc3RzIGVycm9yIGluIGFub3ZhX3Rlc3QoKQ0KICAgICAgZGF0YSAlPiUNCiAgICAgIGRwbHlyOjpzZWxlY3QoISFpZF92YXJfZW5xLCAhIXRpbWVfdmFyX2VucSwgISFjb25kX3Zhcl9lbnEsICEhdmFsdWVfdmFyX2VucSkgDQogICAgDQogICAgIyBBc3N1bXB0aW9ucw0KICAgIGlmKGFzc3VtX2NoZWNrKXsNCiAgICAgIGNhdCgiXG4gT3V0bGllcnMgXG4iKQ0KICAgICAgZGF0YSAlPiUNCiAgICAgICAgZHBseXI6Omdyb3VwX2J5KCEhdGltZV92YXJfZW5xLCAhIWNvbmRfdmFyX2VucSkgJT4lDQogICAgICAgIHJzdGF0aXg6OmlkZW50aWZ5X291dGxpZXJzKCEhdmFsdWVfdmFyX2VucSkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgb3V0bGllcnMgKG5lZWRzIHRvIGJlIDApDQogICAgICAgIHByaW50KCkNCiAgICAgIA0KICAgICAgY2F0KCJcbiBOb3JtYWxpdHkgYXNzdW1wdGlvbiAocD4uMDUpIFxuIikNCiAgICAgIGRhdGEgJT4lDQogICAgICAgIGRwbHlyOjpncm91cF9ieSghIXRpbWVfdmFyX2VucSwgISFjb25kX3Zhcl9lbnEpICU+JQ0KICAgICAgICByc3RhdGl4OjpzaGFwaXJvX3Rlc3QoISF2YWx1ZV92YXJfZW5xKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBub3JtYWxpdHkgYXNzdW1wdGlvbiAocD4uMDUpDQogICAgICAgIHByaW50KCkNCiAgICAgIA0KICAgICAgcXFfcGxvdCA8LSANCiAgICAgICAgZ2dwdWJyOjpnZ3FxcGxvdChkYXRhID0gZGF0YSwgdmFsdWVfdmFyX25hbWUsIGdndGhlbWUgPSB0aGVtZV9idygpLCB0aXRsZSA9ICJRUSBQbG90IikgKw0KICAgICAgICBnZ3Bsb3QyOjpmYWNldF9ncmlkKHZhcnMoISF0aW1lX3Zhcl9lbnEpLCB2YXJzKCEhY29uZF92YXJfZW5xKSwgbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpICAgICMgUVEgcGxvdA0KICAgICAgDQogICAgICBjYXQoIlxuIEhvbW9nbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbiAtIExldmVuZeKAmXMgdGVzdCAocD4uMDUpIFxuIikNCiAgICAgIGRhdGEgJT4lDQogICAgICAgIGdyb3VwX2J5KCEhdGltZV92YXJfZW5xICkgJT4lDQogICAgICAgIGxldmVuZV90ZXN0KGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSkpKSAlPiUNCiAgICAgICAgcHJpbnQoKQ0KICAgICAgDQogICAgICBjYXQoIlxuIEhvbW9nZW5laXR5IG9mIGNvdmFyaWFuY2VzIGFzc3VtcHRpb24gLSBCb3jigJlzIHRlc3Qgb2YgZXF1YWxpdHkgb2YgY292YXJpYW5jZSBtYXRyaWNlcyAocD4uMDAxKSBcbiIpDQogICAgICBib3hfbShkYXRhID0gZGF0YVssIHZhbHVlX3Zhcl9uYW1lLCBkcm9wID0gRkFMU0VdLCBncm91cCA9IGRhdGFbLCBjb25kX3Zhcl9uYW1lLCBkcm9wID0gVFJVRV0pICU+JQ0KICAgICAgICBwcmludA0KICAgIH0NCiAgICANCiAgICAjIFR3by13YXkgcm1BTk9WQSAtIGNoZWNrIGZvciBpbnRlcmFjdGlvbiAoZXguIEYoMiwgMjIpID0gMzAuNCwgcCA8IDAuMDAwMSkNCiAgICBjYXQoIlxuIFR3by13YXkgcm1BTk9WQSBcbiIpDQogICAgcmVzX2FvdiA8LSANCiAgICAgIGFub3ZhX3Rlc3QoZGF0YSA9IGRhdGEsIGR2ID0gISF2YWx1ZV92YXJfZW5xLCB3aWQgPSAhIWlkX3Zhcl9lbnEsICAgICAgICAgICAgICAgIyBhdXRvbWF0aWNhbGx5IGRvZXMgc3BoZXJpY2l0eSBNYXVjaGx54oCZcyB0ZXN0DQogICAgICAgICAgICAgICAgIHdpdGhpbiA9ICEhdGltZV92YXJfZW5xLCBiZXR3ZWVuID0gISFjb25kX3Zhcl9lbnEpDQogICAgZ2V0X2Fub3ZhX3RhYmxlKHJlc19hb3YpICU+JSAgIyBnZXM6IEdyZWVuaG91c2UtR2Vpc3NlciBzcGhlcmljaXR5IGNvcnJlY3Rpb24gaXMgYXV0b21hdGljYWxseSBhcHBsaWVkIHRvIGZhY3RvcnMgdmlvbGF0aW5nIHRoZSBzcGhlcmljaXR5IGFzc3VtcHRpb24gIA0KICAgICAgcHJpbnQoKQ0KICAgIA0KICAgIA0KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQogICAgDQogICAgIy0gUHJvY2VkdXJlIGZvciBhIHNpZ25pZmljYW50IHR3by13YXkgaW50ZXJhY3Rpb24gLQ0KICAgIGlmKHBvc3Rob2Nfc2lnX2ludGVyYWMpew0KICAgICAgY2F0KCJcbiBFZmZlY3Qgb2YgZ3JvdXAgYXQgZWFjaCB0aW1lIHBvaW50IC0gT25lLXdheSBBTk9WQVxuIikNCiAgICAgIG9uZV93YXkgPC0gDQogICAgICAgIGRhdGEgJT4lDQogICAgICAgIGdyb3VwX2J5KCEhdGltZV92YXJfZW5xKSAlPiUNCiAgICAgICAgYW5vdmFfdGVzdChkdiA9ICEhdmFsdWVfdmFyX2VucSwgd2lkID0gISFpZF92YXJfZW5xLCBiZXR3ZWVuID0gISFjb25kX3Zhcl9lbnEpICU+JQ0KICAgICAgICBnZXRfYW5vdmFfdGFibGUoKSAlPiUNCiAgICAgICAgYWRqdXN0X3B2YWx1ZShtZXRob2QgPSBwX2FkanVzdF9tZXRob2QpDQogICAgICBvbmVfd2F5ICU+JSBwcmludCgpDQogICAgICANCiAgICAgIGNhdCgiXG4gUGFpcndpc2UgY29tcGFyaXNvbnMgYmV0d2VlbiBncm91cCBsZXZlbHMgXG4iKQ0KICAgICAgcHdjIDwtIA0KICAgICAgICBkYXRhICU+JQ0KICAgICAgICBncm91cF9ieSghIXRpbWVfdmFyX2VucSkgJT4lDQogICAgICAgIHBhaXJ3aXNlX3RfdGVzdChhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUpKSwgDQogICAgICAgICAgICAgICAgICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QpDQogICAgICBwd2MgJT4lIHByaW50KCkNCiAgICAgIGNhdCgiXG4gRWZmZWN0IG9mIHRpbWUgYXQgZWFjaCBsZXZlbCBvZiBleGVyY2lzZXMgZ3JvdXAgIC0gT25lLXdheSBBTk9WQSBcbiIpDQogICAgICBvbmVfd2F5MiA8LSANCiAgICAgICAgZGF0YSAlPiUNCiAgICAgICAgZ3JvdXBfYnkoISFjb25kX3Zhcl9lbnEpICU+JQ0KICAgICAgICBhbm92YV90ZXN0KGR2ID0gISF2YWx1ZV92YXJfZW5xLCB3aWQgPSAhIWlkX3Zhcl9lbnEsIHdpdGhpbiA9ICEhdGltZV92YXJfZW5xKSAlPiUNCiAgICAgICAgZ2V0X2Fub3ZhX3RhYmxlKCkgJT4lDQogICAgICAgIGFkanVzdF9wdmFsdWUobWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kKQ0KICAgICAgb25lX3dheTIgJT4lIHByaW50KCkNCiAgICAgIA0KICAgICAgY2F0KCJcbiBQYWlyd2lzZSBjb21wYXJpc29ucyBiZXR3ZWVuIHRpbWUgcG9pbnRzIGF0IGVhY2ggZ3JvdXAgbGV2ZWxzICh3ZSBoYXZlIHJlcGVhdGVkIG1lYXN1cmVzIGJ5IHRpbWUpIFxuIikNCiAgICAgIHB3YzIgPC0NCiAgICAgICAgZGF0YSAlPiUNCiAgICAgICAgZ3JvdXBfYnkoISFjb25kX3Zhcl9lbnEpICU+JQ0KICAgICAgICBwYWlyd2lzZV90X3Rlc3QoDQogICAgICAgICAgYXMuZm9ybXVsYShwYXN0ZTAodmFsdWVfdmFyX25hbWUsICIgfiAiLCB0aW1lX3Zhcl9uYW1lKSksICAgICAjIHBhc3RlIGZvcm11bGEsIG5vdCBxdW9zdXJlDQogICAgICAgICAgcGFpcmVkID0gVFJVRSwNCiAgICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QNCiAgICAgICAgKQ0KICAgICAgcHdjMiAgJT4lIHByaW50KCkNCiAgICB9DQogICAgDQogICAgIy0gUHJvY2VkdXJlIGZvciBub24tc2lnbmlmaWNhbnQgdHdvLXdheSBpbnRlcmFjdGlvbi0gDQogICAgIyBJZiB0aGUgaW50ZXJhY3Rpb24gaXMgbm90IHNpZ25pZmljYW50LCB5b3UgbmVlZCB0byBpbnRlcnByZXQgdGhlIG1haW4gZWZmZWN0cyBmb3IgZWFjaCBvZiB0aGUgdHdvIHZhcmlhYmxlczogdHJlYXRtZW50IGFuZCB0aW1lLg0KICAgIGlmKHBvc3Rob2NfbnNfaW50ZXJhYyl7DQogICAgICBjYXQoIlxuIENvbXBhcmlzb25zIGZvciB0cmVhdG1lbnQgdmFyaWFibGUgXG4iKQ0KICAgICAgcHdjX2NvbmQgPC0NCiAgICAgICAgZGF0YSAlPiUNCiAgICAgICAgcGFpcndpc2VfdF90ZXN0KA0KICAgICAgICAgIGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgY29uZF92YXJfbmFtZSkpLCAgICAgIyBwYXN0ZSBmb3JtdWxhLCBub3QgcXVvc3VyZSAgICAgICAgICAgICANCiAgICAgICAgICBwYWlyZWQgPSBGQUxTRSwNCiAgICAgICAgICBwLmFkanVzdC5tZXRob2QgPSBwX2FkanVzdF9tZXRob2QNCiAgICAgICAgKQ0KICAgICAgcHdjX2NvbmQgJT4lIHByaW50KCkNCiAgICAgIGNhdCgiXG4gQ29tcGFyaXNvbnMgZm9yIHRpbWUgdmFyaWFibGUgXG4iKQ0KICAgICAgcHdjX3RpbWUgPC0NCiAgICAgICAgZGF0YSAlPiUgDQogICAgICAgIHBhaXJ3aXNlX3RfdGVzdCgNCiAgICAgICAgICBhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIHRpbWVfdmFyX25hbWUpKSwgICAgICMgcGFzdGUgZm9ybXVsYSwgbm90IHF1b3N1cmUNCiAgICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICAgIHAuYWRqdXN0Lm1ldGhvZCA9IHBfYWRqdXN0X21ldGhvZA0KICAgICAgICApDQogICAgICBwd2NfdGltZSAlPiUgcHJpbnQoKQ0KICAgIH0NCiAgICANCiAgICAjIFZpc3VhbGl6YXRpb24NCiAgICBieF9wbG90IDwtIA0KICAgICAgZ2dib3hwbG90KGRhdGEsIHggPSB0aW1lX3Zhcl9uYW1lLCB5ID0gdmFsdWVfdmFyX25hbWUsDQogICAgICAgICAgICAgICAgY29sb3IgPSBjb25kX3Zhcl9uYW1lLCBwYWxldHRlID0gImpjbyIpDQogICAgcHdjIDwtIA0KICAgICAgcHdjICU+JSANCiAgICAgIGFkZF94eV9wb3NpdGlvbih4ID0gdGltZV92YXJfbmFtZSkNCiAgICBieF9wbG90IDwtIA0KICAgICAgYnhfcGxvdCArIA0KICAgICAgc3RhdF9wdmFsdWVfbWFudWFsKHB3YywgdGlwLmxlbmd0aCA9IDAsIGhpZGUubnMgPSBUUlVFKSArDQogICAgICBsYWJzKA0KICAgICAgICBzdWJ0aXRsZSA9IGdldF90ZXN0X2xhYmVsKHJlc19hb3YsIGRldGFpbGVkID0gVFJVRSksDQogICAgICAgIGNhcHRpb24gPSBnZXRfcHdjX2xhYmVsKHB3YykNCiAgICAgICkNCiAgICANCiAgICBpZihhc3N1bV9jaGVjayl7IA0KICAgICAgbGlzdChxcV9wbG90LCBieF9wbG90KQ0KICAgIH1lbHNlew0KICAgICAgYnhfcGxvdA0KICAgIH0gDQogICAgDQogIH0NCg0KIyBleC4gLSBydW4gb24gbG9uZyBmb3JtYXQNCiMgdHdfbWl4ZWRBTk9WQV9mdW5jKGRhdGEgPSBhbnhpZXR5LCBpZF92YXIgPSBpZCwgY29uZF92YXIgPSBncm91cCwgdGltZV92YXIgPSB0aW1lLCB2YWx1ZV92YXIgPSBzY29yZSwNCiMgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpgYGANCg0KDQoNCiMgUmVhZCwgQ2xlYW4sIFJlY29kZQ0KDQpgYGB7ciByZWRfY2xlYW5fcmVjb2RlX21lcmdlLCByZXN1bHRzPSdoaWRlJywgbWVzc2FnZT1GQUxTRX0NCiN+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQojIFJlYWQsIENsZWFuLCBSZWNvZGUsIFVuaXRlDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KDQojIyBSZWFkIGZpbGVzDQpmb2xkZXIgPC0gIkM6L1VzZXJzL01paGFpL0Rlc2t0b3AvUiBOb3RlYm9va3Mvbm90ZWJvb2tzL00yLXJlcG9ydCINCmZpbGUgPC0gIkRhdGVNMiBmaW5hbC54bHN4Ig0KDQpzZXR3ZChmb2xkZXIpDQpEYXRhX3ByZSA8LSByaW86OmltcG9ydChmaWxlLnBhdGgoZm9sZGVyLCBmaWxlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNraXAgPSAzLCB3aGljaCA9ICJNMiBQUkUiKQ0KDQpEYXRhX3Bvc3QgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMywgd2hpY2ggPSAiTTIgUE9TVCIpDQoNCg0KDQojIFBSRSA9IGNvbG5hbWVzKERhdGFfcHJlKTsgUE9TVCA9IGNvbG5hbWVzKERhdGFfcG9zdCkgDQojIGNiaW5kKFBSRSwgUE9TVCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICJzMS43IiB2YXIgaXMgbWlzc2luZyBmb3JtIFBPU1QgLS0gbWlzc21hdGNoIHJvdyAxMg0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhbHNvIG1pc3NpbmcgInMyLjciIGFuZCBvdGhlcnMNCg0KDQojIGluZGV4IGZyb20gIkRhdGVNMi54bHN4Ig0KIyBpbmRleF9yeWZmX3ByZSA8LSA5NDoxMzUNCiMgaW5kZXhfcHNzX3ByZSA8LSAxMzY6MTQ5DQojIGluZGV4X3J5ZmZfcG9zdCA8LSA5NDoxMzUgLSA1DQojIGluZGV4X3Bzc19wb3N0IDwtIDEzNjoxNDkgLSA1DQoNCmluZGV4X3J5ZmZfcHJlIDwtIDgzOjEyNA0KaW5kZXhfcHNzX3ByZSA8LSAxMjU6MTM4DQppbmRleF9yeWZmX3Bvc3QgPC0gODE6MTIyDQppbmRleF9wc3NfcG9zdCA8LSAxMjM6MTM2DQoNCg0KY29sbmFtZXMoRGF0YV9wcmUpWzFdIDwtICJJRCINCmNvbG5hbWVzKERhdGFfcHJlKVtjb2xuYW1lcyhEYXRhX3ByZSkgPT0gIlN0cmVzIHByZSJdIDwtICJWQVNfc3RyZXNzX3ByZSINCmNvbG5hbWVzKERhdGFfcHJlKVtjb2xuYW1lcyhEYXRhX3ByZSkgPT0gIlN0cmVzIHBvc3QiXSA8LSAiVkFTX3N0cmVzc19wb3N0Ig0KY29sbmFtZXMoRGF0YV9wcmUpW2luZGV4X3J5ZmZfcHJlXSA8LSBzcHJpbnRmKCJyeWZmXyUwMWQiLCBzZXEoMSwgNDIpKQ0KY29sbmFtZXMoRGF0YV9wcmUpW2luZGV4X3Bzc19wcmVdIDwtIHNwcmludGYoInBzc18lMDFkIiwgc2VxKDEsIDE0KSkNCkRhdGFfcHJlIDwtDQogIERhdGFfcHJlICU+JQ0KICBkcm9wX25hKElEKSAlPiUNCiAgZHBseXI6Om11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIGxpc3QofmRwbHlyOjpuYV9pZiguLCAibmEiKSkpIA0KRGF0YV9wcmVbaW5kZXhfcnlmZl9wcmVdIDwtIGNvbHN0b251bWVyaWMoRGF0YV9wcmVbaW5kZXhfcnlmZl9wcmVdKQ0KRGF0YV9wcmUkcHNzXzhbRGF0YV9wcmUkcHNzXzggPT0gIisrKysrKyJdIDwtIE5BICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0eXBvDQpEYXRhX3ByZVtpbmRleF9wc3NfcHJlXSA8LSBjb2xzdG9udW1lcmljKERhdGFfcHJlW2luZGV4X3Bzc19wcmVdKQ0KDQpjb2xuYW1lcyhEYXRhX3Bvc3QpWzFdIDwtICJJRCINCmNvbG5hbWVzKERhdGFfcG9zdClbY29sbmFtZXMoRGF0YV9wb3N0KSA9PSAiU3RyZXMgcHJlIl0gPC0gIlZBU19zdHJlc3NfcHJlIg0KY29sbmFtZXMoRGF0YV9wb3N0KVtjb2xuYW1lcyhEYXRhX3Bvc3QpID09ICJTdHJlcyBwb3N0Il0gPC0gIlZBU19zdHJlc3NfcG9zdCINCmNvbG5hbWVzKERhdGFfcG9zdClbaW5kZXhfcnlmZl9wb3N0XSA8LSBzcHJpbnRmKCJyeWZmXyUwMWQiLCBzZXEoMSwgNDIpKQ0KY29sbmFtZXMoRGF0YV9wb3N0KVtpbmRleF9wc3NfcG9zdF0gPC0gc3ByaW50ZigicHNzXyUwMWQiLCBzZXEoMSwgMTQpKQ0KRGF0YV9wb3N0IDwtDQogIERhdGFfcG9zdCAlPiUNCiAgZHBseXI6Om11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIGxpc3QofmRwbHlyOjpuYV9pZiguLCAibmEiKSkpIA0KRGF0YV9wb3N0W2luZGV4X3J5ZmZfcG9zdF0gPC0gY29sc3RvbnVtZXJpYyhEYXRhX3Bvc3RbaW5kZXhfcnlmZl9wb3N0XSkNCkRhdGFfcG9zdFtpbmRleF9wc3NfcG9zdF0gPC0gY29sc3RvbnVtZXJpYyhEYXRhX3Bvc3RbaW5kZXhfcHNzX3Bvc3RdKQ0KDQojIHR5cG9zDQojIGNoZWNrX251bWVyaWMgPC0gYXMuZGF0YS5mcmFtZShzYXBwbHkoRGF0YV9wcmVbaW5kZXhfcHNzX3ByZV0sIHZhcmhhbmRsZTo6Y2hlY2subnVtZXJpYykpIA0KIyBzYXBwbHkoY2hlY2tfbnVtZXJpYywgZnVuY3Rpb24oeCkgbGVuZ3RoKHdoaWNoKCF4KSkpDQoNCmNvbG5hbWVzKERhdGFfcHJlKVtjb2xuYW1lcyhEYXRhX3ByZSkgPT0gInMxLjEuIl0gPC0gInMxLjEiDQpjb2xuYW1lcyhEYXRhX3Bvc3QpW2NvbG5hbWVzKERhdGFfcG9zdCkgPT0gInMxLjEuIl0gPC0gInMxLjEiDQoNCkRhdGFfcG9zdCRzMi4xMFt3aGljaChEYXRhX3Bvc3QkczIuMTAgPT0gIi4iKV0gPC0gTkENCkRhdGFfcG9zdCRzMi4xMCA8LSBhcy5udW1lcmljKERhdGFfcG9zdCRzMi4xMCkNCkRhdGFfcG9zdCRzMy4xNlt3aGljaChEYXRhX3Bvc3QkczMuMTYgPT0gImtxIildIDwtIE5BDQpEYXRhX3Bvc3QkczMuMTYgPC0gYXMubnVtZXJpYyhEYXRhX3Bvc3QkczMuMTYpDQoNCmBgYA0KDQoNCg0KYGBge3Igc2NvcmluZywgcmVzdWx0cz0naGlkZSd9DQojIyBQU1MtU0YgMTQgKGxpa2VydCAwLTQpDQojIEl0ZW1zIDQsIDUsIDYsIDcsIDksIDEwLCBhbmQgMTMgYXJlIHNjb3JlZCBpbiByZXZlcnNlIGRpcmVjdGlvbi4NCg0KaW5kZXhpdGVtX3JldlBTUyA8LSBjKDQsIDUsIDYsIDcsIDksIDEwLCAxMykNCg0KRGF0YV9wcmVbLCBpbmRleF9wc3NfcHJlXVtpbmRleGl0ZW1fcmV2UFNTXSA8LSBSZXZlcnNlQ29kZShEYXRhX3ByZVssIGluZGV4X3Bzc19wcmVdW2luZGV4aXRlbV9yZXZQU1NdLCB0b251bWVyaWMgPSBGQUxTRSwgbWluID0gMCwgbWF4ID0gNCkNCkRhdGFfcG9zdFssIGluZGV4X3Bzc19wb3N0XVtpbmRleGl0ZW1fcmV2UFNTXSA8LSBSZXZlcnNlQ29kZShEYXRhX3Bvc3RbLCBpbmRleF9wc3NfcG9zdF1baW5kZXhpdGVtX3JldlBTU10sIHRvbnVtZXJpYyA9IEZBTFNFLCBtaW4gPSAwLCBtYXggPSA0KQ0KDQpEYXRhX3ByZSRQU1MgPC0gU2NvcmVMaWtlcnQoRGF0YV9wcmVbLCBpbmRleF9wc3NfcHJlXSwgbmFwZXJjZW50ID0gLjQpDQpEYXRhX3Bvc3QkUFNTIDwtIFNjb3JlTGlrZXJ0KERhdGFfcG9zdFssIGluZGV4X3Bzc19wb3N0XSwgbmFwZXJjZW50ID0gLjQpDQogIA0KDQojIyBSeWZmIChsaWtlcnQgMS02KQ0KIyBSZWNvZGUgbmVnYXRpdmUgcGhyYXNlZCBpdGVtczogIDMsNSwxMCwxMywxNCwxNSwxNiwxNywxOCwxOSwyMywyNiwyNywzMCwzMSwzMiwzNCwzNiwzOSw0MS4NCiMgQXV0b25vbXk6IDEsNywxMywxOSwyNSwzMSwzNw0KIyBFbnZpcm9ubWVudGFsIG1hc3Rlcnk6IDIsOCwxNCwyMCwyNiwzMiwzOA0KIyBQZXJzb25hbCBHcm93dGg6IDMsOSwxNSwyMSwyNywzMywzOQ0KIyBQb3NpdGl2ZSBSZWxhdGlvbnM6IDQsMTAsMTYsMjIsMjgsMzQsNDANCiMgUHVycG9zZSBpbiBsaWZlOiA1LDExLDE3LDIzLDI5LDM1LDQxDQojIFNlbGYtYWNjZXB0YW5jZTogNiwxMiwxOCwyNCwzMCwzNiw0Mg0KDQppbmRleGl0ZW1fcmV2UllGRiA8LSBjKDMsNSwxMCwxMywxNCwxNSwxNiwxNywxOCwxOSwyMywyNiwyNywzMCwzMSwzMiwzNCwzNiwzOSw0MSkNCg0KRGF0YV9wcmVbLCBpbmRleF9yeWZmX3ByZV1baW5kZXhpdGVtX3JldlJZRkZdIDwtIFJldmVyc2VDb2RlKERhdGFfcHJlWywgaW5kZXhfcnlmZl9wcmVdW2luZGV4aXRlbV9yZXZSWUZGXSwgdG9udW1lcmljID0gRkFMU0UsIG1pbiA9IDEsIG1heCA9IDYpDQpEYXRhX3Bvc3RbLCBpbmRleF9yeWZmX3Bvc3RdW2luZGV4aXRlbV9yZXZSWUZGXSA8LSBSZXZlcnNlQ29kZShEYXRhX3Bvc3RbLCBpbmRleF9yeWZmX3Bvc3RdW2luZGV4aXRlbV9yZXZSWUZGXSwgdG9udW1lcmljID0gRkFMU0UsIG1pbiA9IDEsIG1heCA9IDYpDQoNCmluZGV4aXRlbV9BdXRvIDwtIGMoMSw3LDEzLDE5LDI1LDMxLDM3KQ0KaW5kZXhpdGVtX0Vudk0gPC0gYygyLDgsMTQsMjAsMjYsMzIsMzgpDQppbmRleGl0ZW1fUGVyc0cgPC0gYygzLDksMTUsMjEsMjcsMzMsMzkpDQppbmRleGl0ZW1fUG9zUmVsIDwtIGMoNCwxMCwxNiwyMiwyOCwzNCw0MCkNCmluZGV4aXRlbV9QdXJMaWYgPC0gYyg1LDExLDE3LDIzLDI5LDM1LDQxKQ0KaW5kZXhpdGVtX1NlbGZBYyA8LSBjKDYsMTIsMTgsMjQsMzAsMzYsNDIpDQoNCg0KRGF0YV9wcmUkQXV0byA8LSBTY29yZUxpa2VydChEYXRhX3ByZVssIGluZGV4X3J5ZmZfcHJlXVtpbmRleGl0ZW1fQXV0b10sIG5hcGVyY2VudCA9IC40KQ0KRGF0YV9wcmUkRW52TSA8LSBTY29yZUxpa2VydChEYXRhX3ByZVssIGluZGV4X3J5ZmZfcHJlXVtpbmRleGl0ZW1fRW52TV0sIG5hcGVyY2VudCA9IC40KQ0KRGF0YV9wcmUkUGVyc0cgPC0gU2NvcmVMaWtlcnQoRGF0YV9wcmVbLCBpbmRleF9yeWZmX3ByZV1baW5kZXhpdGVtX1BlcnNHXSwgbmFwZXJjZW50ID0gLjQpDQpEYXRhX3ByZSRQb3NSZWwgPC0gU2NvcmVMaWtlcnQoRGF0YV9wcmVbLCBpbmRleF9yeWZmX3ByZV1baW5kZXhpdGVtX1Bvc1JlbF0sIG5hcGVyY2VudCA9IC40KQ0KRGF0YV9wcmUkUHVyTGlmIDwtIFNjb3JlTGlrZXJ0KERhdGFfcHJlWywgaW5kZXhfcnlmZl9wcmVdW2luZGV4aXRlbV9QdXJMaWZdLCBuYXBlcmNlbnQgPSAuNCkNCkRhdGFfcHJlJFNlbGZBYyA8LSBTY29yZUxpa2VydChEYXRhX3ByZVssIGluZGV4X3J5ZmZfcHJlXVtpbmRleGl0ZW1fU2VsZkFjXSwgbmFwZXJjZW50ID0gLjQpDQoNCkRhdGFfcG9zdCRBdXRvIDwtIFNjb3JlTGlrZXJ0KERhdGFfcG9zdFssIGluZGV4X3J5ZmZfcG9zdF1baW5kZXhpdGVtX0F1dG9dLCBuYXBlcmNlbnQgPSAuNCkNCkRhdGFfcG9zdCRFbnZNIDwtIFNjb3JlTGlrZXJ0KERhdGFfcG9zdFssIGluZGV4X3J5ZmZfcG9zdF1baW5kZXhpdGVtX0Vudk1dLCBuYXBlcmNlbnQgPSAuNCkNCkRhdGFfcG9zdCRQZXJzRyA8LSBTY29yZUxpa2VydChEYXRhX3Bvc3RbLCBpbmRleF9yeWZmX3Bvc3RdW2luZGV4aXRlbV9QZXJzR10sIG5hcGVyY2VudCA9IC40KQ0KRGF0YV9wb3N0JFBvc1JlbCA8LSBTY29yZUxpa2VydChEYXRhX3Bvc3RbLCBpbmRleF9yeWZmX3Bvc3RdW2luZGV4aXRlbV9Qb3NSZWxdLCBuYXBlcmNlbnQgPSAuNCkNCkRhdGFfcG9zdCRQdXJMaWYgPC0gU2NvcmVMaWtlcnQoRGF0YV9wb3N0WywgaW5kZXhfcnlmZl9wb3N0XVtpbmRleGl0ZW1fUHVyTGlmXSwgbmFwZXJjZW50ID0gLjQpDQpEYXRhX3Bvc3QkU2VsZkFjIDwtIFNjb3JlTGlrZXJ0KERhdGFfcG9zdFssIGluZGV4X3J5ZmZfcG9zdF1baW5kZXhpdGVtX1NlbGZBY10sIG5hcGVyY2VudCA9IC40KQ0KDQojIyBTYXZlIFNjb3Jlcw0KIyByaW86OmV4cG9ydChEYXRhX3ByZVssIGMoMSwgMTUwOjE1NildKQ0KIyByaW86OmV4cG9ydChEYXRhX3Bvc3RbLCBjKDEsIDE0OToxNTUpXSkNCiMgbmxhc3Rjb2wgPC0gNw0KIyByaW86OmV4cG9ydChsaXN0KFBSRSA9IERhdGFfcHJlWywgYygxLCAobmNvbChEYXRhX3ByZSktbmxhc3Rjb2wrMSk6bmNvbChEYXRhX3ByZSkpXSwgUE9TVCA9IERhdGFfcG9zdFssIGMoMSwgKG5jb2woRGF0YV9wb3N0KS1ubGFzdGNvbCsxKTpuY29sKERhdGFfcG9zdCkpXSksIA0KIyAgICAgICAgICAgICAiTTIgUFNTIFJ5ZmYgZmluYWwueGxzeCIpDQoNCkRhdGFfcHJlJFMxX01lYW4gPC0gcm93TWVhbnMoRGF0YV9wcmVbLCBzcHJpbnRmKCJzMS4lZCIsIGMoMTo2LCA4OjE2KSldLCBuYS5ybSA9IFRSVUUpICAjIERhdGFfcHJlWywgZ3JlcCgiczEuIiwgY29sbmFtZXMoRGF0YV9wcmUpKV0NCkRhdGFfcHJlJFMyX01lYW4gPC0gcm93TWVhbnMoRGF0YV9wcmVbLCBzcHJpbnRmKCJzMi4lZCIsIGMoMTo2LCA4OjE2KSldLCBuYS5ybSA9IFRSVUUpICAjIERhdGFfcHJlWywgZ3JlcCgiczIuIiwgY29sbmFtZXMoRGF0YV9wcmUpKV0NCkRhdGFfcHJlJFMzX01lYW4gPC0gcm93TWVhbnMoRGF0YV9wcmVbLCBzcHJpbnRmKCJzMy4lZCIsIGMoMTo2LCA4OjE2KSldLCBuYS5ybSA9IFRSVUUpICAjIERhdGFfcHJlWywgZ3JlcCgiczMuIiwgY29sbmFtZXMoRGF0YV9wcmUpKV0NCg0KRGF0YV9wb3N0JFMxX01lYW4gPC0gcm93TWVhbnMoRGF0YV9wb3N0Wywgc3ByaW50ZigiczEuJWQiLCBjKDE6NiwgODoxNikpXSwgbmEucm0gPSBUUlVFKSAgIyBEYXRhX3Bvc3RbLCBncmVwKCJzMS4iLCBjb2xuYW1lcyhEYXRhX3Bvc3QpKV0NCkRhdGFfcG9zdCRTMl9NZWFuIDwtIHJvd01lYW5zKERhdGFfcG9zdFssIHNwcmludGYoInMyLiVkIiwgYygxOjYsIDg6MTYpKV0sIG5hLnJtID0gVFJVRSkgICMgRGF0YV9wb3N0WywgZ3JlcCgiczIuIiwgY29sbmFtZXMoRGF0YV9wb3N0KSldDQpEYXRhX3Bvc3QkUzNfTWVhbiA8LSByb3dNZWFucyhEYXRhX3Bvc3RbLCBzcHJpbnRmKCJzMy4lZCIsIGMoMTo2LCA4OjE2KSldLCBuYS5ybSA9IFRSVUUpICAjIERhdGFfcG9zdFssIGdyZXAoInMzLiIsIGNvbG5hbWVzKERhdGFfcG9zdCkpXQ0KYGBgDQoNCg0KIyBBZGQgVFIgJiBDVFJMIGdyb3Vwcw0KDQpgYGB7ciBjb25kZ3JvdXBzX2RmfQ0KdHJfaWRzIDwtIHBhc3RlMChjKDEsIDIsIDQsIDUsIDYsIDEwLCAxMywgMTQsIDE1LCAxNiwgMjQsIDI1LCAyNiwgMzIsIDM0LCAzNSwgMzksIDQwLCA0MiwgNDYsIDQ3LCA0OCwgNTEsIDUzLCA1OSwgNjAsIDYyLCA2MywgNjQpLCAiIE0yIikgDQpjdHJsX2lkcyA8LSBwYXN0ZTAoYygzLCA3LCA4LCA5LCAxMSwgMTIsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNywgMjgsIDMwLCAzMywgMzYsIDM3LCAzOCwgNDEsIDQzLCA0NSwgNDksIDUyLCA1NCwgNTUsIDU2LCA1NywgNTgpLCAiIE0yIikgDQojIFN1YmogZnJvbSBUUjogRGF0YV9wcmVbd2hpY2goRGF0YV9wcmUkSUQgJWluJSB0cl9pZHMpLF0gIA0KIyBTdWJqIGZyb20gQ1RSTDogRGF0YV9wcmVbd2hpY2goRGF0YV9wcmUkSUQgJWluJSBjdHJsX2lkcyksXSANCg0KRGF0YV9wcmUkQ29uZCA8LSBkcGx5cjo6Y2FzZV93aGVuKERhdGFfcHJlJElEICVpbiUgdHJfaWRzIH4gIlRSIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhX3ByZSRJRCAlaW4lIGN0cmxfaWRzIH4gIkNUUkwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBOQV9jaGFyYWN0ZXJfKQ0KRGF0YV9wb3N0JENvbmQgPC0gZHBseXI6OmNhc2Vfd2hlbihEYXRhX3Bvc3QkSUQgJWluJSB0cl9pZHMgfiAiVFIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFfcG9zdCRJRCAlaW4lIGN0cmxfaWRzIH4gIkNUUkwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBOQV9jaGFyYWN0ZXJfKQ0KYGBgDQoNCg0KIyBVbml0ZSBkYXRhIGZyYW1lcw0KDQpgYGB7ciB1bml0ZV9kZn0NCmNhdCgiIyMgTnVtYmVyIG9mIHN1YmplY3RzIGluIHByZSIpDQpEYXRhX3ByZSAlPiUgDQogZHBseXI6OnN1bW1hcmlzZShjb3VudCA9IGRwbHlyOjpuX2Rpc3RpbmN0KElEKSkNCg0KY2F0KCIjIyBOdW1iZXIgb2Ygc3ViamVjdHMgaW4gcG9zdCIpDQpEYXRhX3Bvc3QgJT4lDQogZHBseXI6OnN1bW1hcmlzZShjb3VudCA9IGRwbHlyOjpuX2Rpc3RpbmN0KElEKSkNCg0KRGF0YV9wcmUkUHJlUG9zdCA8LSByZXAoIlByZSIsIG5yb3coRGF0YV9wcmUpKQ0KRGF0YV9wb3N0JFByZVBvc3QgPC0gcmVwKCJQb3N0IiwgbnJvdyhEYXRhX3Bvc3QpKQ0KDQpEYXRhX3ByZV9zY2FsZXMgPC0gRGF0YV9wcmVbLCBjKCJJRCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVkFTX3N0cmVzc19wcmUiLCAiVkFTX3N0cmVzc19wb3N0IiwgIlBTUyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXV0byIsICJFbnZNIiwgIlBlcnNHIiwgIlBvc1JlbCIsICJQdXJMaWYiLCAgIlNlbGZBYyIsICJTMV9NZWFuIiwgIlMyX01lYW4iLCAiUzNfTWVhbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJlUG9zdCIsICJDb25kIildDQpEYXRhX3Bvc3Rfc2NhbGVzIDwtIERhdGFfcG9zdFssIGMoIklEIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlZBU19zdHJlc3NfcHJlIiwgIlZBU19zdHJlc3NfcG9zdCIsICJQU1MiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXV0byIsICJFbnZNIiwgIlBlcnNHIiwgIlBvc1JlbCIsICJQdXJMaWYiLCAgIlNlbGZBYyIsICJTMV9NZWFuIiwgIlMyX01lYW4iLCAiUzNfTWVhbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcmVQb3N0IiwgIkNvbmQiKV0NCg0KRGF0YV91bmlmX2xvbmcgPC0gcmJpbmQoRGF0YV9wcmVfc2NhbGVzLCBEYXRhX3Bvc3Rfc2NhbGVzKQ0KRGF0YV91bmlmX3dpZGUgPC0NCiAgRGF0YV91bmlmX2xvbmcgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gUHJlUG9zdCwgdmFsdWVzX2Zyb20gPSBjKFZBU19zdHJlc3NfcHJlLCBWQVNfc3RyZXNzX3Bvc3QsIFBTUywgQXV0bywgRW52TSwgUGVyc0csIFBvc1JlbCwgUHVyTGlmLCBTZWxmQWMsIFMxX01lYW4sIFMyX01lYW4sIFMzX01lYW4pKQ0KDQpEYXRhX3VuaWZfbG9uZyA8LQ0KICBEYXRhX3VuaWZfbG9uZyAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKElEID0gYXMuZmFjdG9yKElEKSwNCiAgICAgICAgICAgICAgICAgIENvbmQgPSBhcy5mYWN0b3IoQ29uZCksDQogICAgICAgICAgICAgICAgICBQcmVQb3N0ID0gYXMuZmFjdG9yKFByZVBvc3QpKSAlPiUNCiAgIGRwbHlyOjptdXRhdGUoVmFzX0RpZmYgPSBWQVNfc3RyZXNzX3Bvc3QgLSBWQVNfc3RyZXNzX3ByZSwNCiAgICAgICAgICAgICAgICAgVmFzX01lYW4gPSByb3dNZWFucyhkcGx5cjo6c2VsZWN0KC5kYXRhID0gLiwgVkFTX3N0cmVzc19wb3N0LCBWQVNfc3RyZXNzX3ByZSksIG5hLnJtID0gVFJVRSkpDQpgYGANCg0KDQojIyBFeHBvcnQgZGF0YSBmb3IgUk1OIGluIHNwZWNpZmllZCBvcmRlcg0KDQpgYGB7ciBkZl9leHBvcnRfcm1ufQ0KIyBybW5fb3JkZXJfaWRzIDwtIGMoMSwgMTQsIDEzLCA2LCA0LCA1LCAxMCwgMTUsIDIsIDE2LCA0MiwgMzQsIDI0LCAyNSwgMjYsIDM1LCAzOSwgNDAsIDMyLCA1OSwgNTMsIDY0LCA0NiwgNDcsIDYyLCA2MywgNDgsIDUxLCA2MCwgDQojICAgICAgICAgICAgICAgICAgICA4LCAyMCwgMTIsIDE4LCA5LCAxNywgMTksIDcsIDMsIDQzLCA0MSwgMjcsIDIzLCAzOCwgMjIsIDMzLCAyOCwgMzAsIDIxLCAzNywgNDksIDU2LCA1OCwgNTcsIDUyLCA0NSwgNTUsIDU0KQ0KIyBybW5fb3JkZXJfaWRzIDwtIHBhc3RlMChybW5fb3JkZXJfaWRzLCAiIE0yIikNCiMgDQojIFJNTl9kZiA8LSBEYXRhX3VuaWZfd2lkZSBbbWF0Y2gocm1uX29yZGVyX2lkcywgRGF0YV91bmlmX3dpZGUgJElEKSxdICAgICMgb25seSA1NyBzdWJqcyBmb3IgUk1ODQojIA0KIyByaW86OmV4cG9ydChSTU5fZGYsICJSTU4gb3JkZXJlZCBNMi54bHN4IikNCmBgYA0KDQoNCjwhLS0gRG8gaXQgYnkgY29uZGl0aW9uLCBuZWVkIEFOQ09WQSBQb3N0DQoNCmBgYHtyIHRfdGVzdCwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NywgcmVzdWx0cz0nYXNpcycsIHdhcm5pbmc9RkFMU0V9DQpjYXQoIiMjIyBQU1MiKQ0KZnVuY190X2JveChEYXRhX3VuaWZfd2lkZSwgIklEIiwgIlBTU19QcmUiLCAiUFNTX1Bvc3QiKQ0KDQpjYXQoIiMjIyBSeWZmIikNCmZ1bmNfdF9ib3goRGF0YV91bmlmX3dpZGUsICJJRCIsICJBdXRvX1ByZSIsICJBdXRvX1Bvc3QiKQ0KZnVuY190X2JveChEYXRhX3VuaWZfd2lkZSwgIklEIiwgIkVudk1fUHJlIiwgIkVudk1fUG9zdCIpDQpmdW5jX3RfYm94KERhdGFfdW5pZl93aWRlLCAiSUQiLCAiUGVyc0dfUHJlIiwgIlBlcnNHX1Bvc3QiKQ0KZnVuY190X2JveChEYXRhX3VuaWZfd2lkZSwgIklEIiwgIlBvc1JlbF9QcmUiLCAiUG9zUmVsX1Bvc3QiKQ0KZnVuY190X2JveChEYXRhX3VuaWZfd2lkZSwgIklEIiwgIlB1ckxpZl9QcmUiLCAiUHVyTGlmX1Bvc3QiKQ0KZnVuY190X2JveChEYXRhX3VuaWZfd2lkZSwgIklEIiwgIlNlbGZBY19QcmUiLCAiU2VsZkFjX1Bvc3QiKQ0KDQoNCmNhdCgiIyMjIE1lbW9yeSBTY2FsZXMiKQ0KZnVuY190X2JveChEYXRhX3VuaWZfd2lkZSwgIklEIiwgIlMxX01lYW5fUHJlIiwgIlMxX01lYW5fUG9zdCIpDQpmdW5jX3RfYm94KERhdGFfdW5pZl93aWRlLCAiSUQiLCAiUzJfTWVhbl9QcmUiLCAiUzJfTWVhbl9Qb3N0IikNCmZ1bmNfdF9ib3goRGF0YV91bmlmX3dpZGUsICJJRCIsICJTM19NZWFuX1ByZSIsICJTM19NZWFuX1Bvc3QiKQ0KYGBgDQoNCi0tPg0KDQoNCiMgQU5DT1ZBIFBvc3QNCg0KYGBge3IgcmVzX0FOQ09WQVBvc3QsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTcsIHJlc3VsdHM9J2FzaXMnLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KY2F0KCIjIyBQU1MiKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBQU1MsIGNvbmRfdmFyID0gQ29uZCwgYXNzdW1fY2hlY2sgPSBUUlVFLCBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpDQoNCmNhdCgiIyMgQXV0byIpDQpBTkNPVkFQb3N0X2Z1bmMoZGF0YSA9IERhdGFfdW5pZl9sb25nLCBpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCBwcmVfbGFiZWwgPSBQcmUsIHBvc3RfbGFiZWwgPSBQb3N0LA0KICAgICAgICAgICAgICAgIHZhbHVlX3ZhciA9IEF1dG8sIGNvbmRfdmFyID0gQ29uZCwgYXNzdW1fY2hlY2sgPSBUUlVFLCBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpDQoNCmNhdCgiIyMgRW52TSIpDQpBTkNPVkFQb3N0X2Z1bmMoZGF0YSA9IERhdGFfdW5pZl9sb25nLCBpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCBwcmVfbGFiZWwgPSBQcmUsIHBvc3RfbGFiZWwgPSBQb3N0LA0KICAgICAgICAgICAgICAgIHZhbHVlX3ZhciA9IEVudk0sIGNvbmRfdmFyID0gQ29uZCwgYXNzdW1fY2hlY2sgPSBUUlVFLCBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpDQoNCmNhdCgiIyMgUGVyc0ciKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBQZXJzRywgY29uZF92YXIgPSBDb25kLCBhc3N1bV9jaGVjayA9IFRSVUUsIHBfYWRqdXN0X21ldGhvZCA9ICJib25mZXJyb25pIikNCg0KY2F0KCIjIyBQb3NSZWwiKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBQb3NSZWwsIGNvbmRfdmFyID0gQ29uZCwgYXNzdW1fY2hlY2sgPSBUUlVFLCBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpDQoNCmNhdCgiIyMgUHVyTGlmIikNCkFOQ09WQVBvc3RfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHByZV9sYWJlbCA9IFByZSwgcG9zdF9sYWJlbCA9IFBvc3QsDQogICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gUHVyTGlmLCBjb25kX3ZhciA9IENvbmQsIGFzc3VtX2NoZWNrID0gVFJVRSwgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KDQpjYXQoIiMjIFNlbGZBYyIpDQpBTkNPVkFQb3N0X2Z1bmMoZGF0YSA9IERhdGFfdW5pZl9sb25nLCBpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCBwcmVfbGFiZWwgPSBQcmUsIHBvc3RfbGFiZWwgPSBQb3N0LA0KICAgICAgICAgICAgICAgIHZhbHVlX3ZhciA9IFNlbGZBYywgY29uZF92YXIgPSBDb25kLCBhc3N1bV9jaGVjayA9IFRSVUUsIHBfYWRqdXN0X21ldGhvZCA9ICJib25mZXJyb25pIikNCg0KDQpjYXQoIiMjIFMxX01lYW4iKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBTMV9NZWFuLCBjb25kX3ZhciA9IENvbmQsIGFzc3VtX2NoZWNrID0gVFJVRSwgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KDQpjYXQoIiMjIFMyX01lYW4iKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBTMl9NZWFuLCBjb25kX3ZhciA9IENvbmQsIGFzc3VtX2NoZWNrID0gVFJVRSwgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KDQpjYXQoIiMjIFMzX01lYW4iKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBTM19NZWFuLCBjb25kX3ZhciA9IENvbmQsIGFzc3VtX2NoZWNrID0gVFJVRSwgcF9hZGp1c3RfbWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KDQpjYXQoIiMjIFZhc19EaWZmIikNCkFOQ09WQVBvc3RfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHByZV9sYWJlbCA9IFByZSwgcG9zdF9sYWJlbCA9IFBvc3QsDQogICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gVmFzX0RpZmYsIGNvbmRfdmFyID0gQ29uZCwgYXNzdW1fY2hlY2sgPSBUUlVFLCBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpDQoNCmNhdCgiIyMgVmFzX01lYW4iKQ0KQU5DT1ZBUG9zdF9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgcHJlX2xhYmVsID0gUHJlLCBwb3N0X2xhYmVsID0gUG9zdCwNCiAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBWYXNfTWVhbiwgY29uZF92YXIgPSBDb25kLCBhc3N1bV9jaGVjayA9IFRSVUUsIHBfYWRqdXN0X21ldGhvZCA9ICJib25mZXJyb25pIikNCmBgYA0KDQojIE1peGVkIEFOT1ZBDQoNCmBgYHtyIHJlc19taXhlZEFOT1ZBLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD03LCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmNhdCgiIyMgUFNTIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gUFNTLCBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCIjIyBBdXRvIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gQXV0bywgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgRW52TSIpDQp0d19taXhlZEFOT1ZBX2Z1bmMoZGF0YSA9IERhdGFfdW5pZl9sb25nLCBpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIA0KICAgICAgICAgICAgICAgICAgIHZhbHVlX3ZhciA9IEVudk0sIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIFBlcnNHIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gUGVyc0csIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIFBvc1JlbCIpDQp0d19taXhlZEFOT1ZBX2Z1bmMoZGF0YSA9IERhdGFfdW5pZl9sb25nLCBpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIA0KICAgICAgICAgICAgICAgICAgIHZhbHVlX3ZhciA9IFBvc1JlbCwgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgUHVyTGlmIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gUHVyTGlmLCBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCIjIyBTZWxmQWMiKQ0KdHdfbWl4ZWRBTk9WQV9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCANCiAgICAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBTZWxmQWMsIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIFMxX01lYW4iKQ0KdHdfbWl4ZWRBTk9WQV9mdW5jKGRhdGEgPSBEYXRhX3VuaWZfbG9uZywgaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCANCiAgICAgICAgICAgICAgICAgICB2YWx1ZV92YXIgPSBTMV9NZWFuLCBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KY2F0KCIjIyBTMl9NZWFuIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gUzJfTWVhbiwgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgUzNfTWVhbiIpDQp0d19taXhlZEFOT1ZBX2Z1bmMoZGF0YSA9IERhdGFfdW5pZl9sb25nLCBpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIA0KICAgICAgICAgICAgICAgICAgIHZhbHVlX3ZhciA9IFMzX01lYW4sIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIFZhc19EaWZmIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gVmFzX0RpZmYsIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIFZhc19NZWFuIikNCnR3X21peGVkQU5PVkFfZnVuYyhkYXRhID0gRGF0YV91bmlmX2xvbmcsIGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgDQogICAgICAgICAgICAgICAgICAgdmFsdWVfdmFyID0gVmFzX01lYW4sIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KYGBgDQoNCg0KDQo8IS0tIFNlc3Npb24gSW5mbyBhbmQgTGljZW5zZSAtLT4NCg0KPGJyPg0KDQojIFNlc3Npb24gSW5mbw0KYGBge3Igc2Vzc2lvbl9pbmZvLCBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30NCnNlc3Npb25JbmZvKCkgICAgDQpgYGANCg0KPCEtLSBGb290ZXIgLS0+DQombmJzcDsNCjxociAvPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPkEgd29yayBieSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vQ2xhdWRpdVBhcGFzdGVyaS8iPkNsYXVkaXUgUGFwYXN0ZXJpPC9hPjwvcD4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48c3BhbiBzdHlsZT0iY29sb3I6ICM4MDgwODA7Ij48ZW0+Y2xhdWRpdS5wYXBhc3RlcmlAZ21haWwuY29tPC9lbT48L3NwYW4+PC9wPg0KJm5ic3A7DQo=